Svelte中兄弟组件传值及子页面向父布局Nav组件传标题方案
Alright, let's tackle this problem properly—you need a scalable, Routify-friendly way to pass custom nav titles (including HTML content) from your child pages to the shared Nav component in _layout.svelte, while keeping a default fallback and supporting SPA page transitions. Here's a step-by-step solution that's easy to extend:
First, update your Nav.svelte to accept a navTitle prop with a default value, and use Svelte's {@html} directive to render HTML content safely:
<!-- Nav.svelte --> <script> // Set default title if no value is passed export let navTitle = "MyApp"; </script> <nav class="app-nav"> <!-- Use {@html} to render plain text or HTML content --> <h1 class="nav-title">{@html navTitle}</h1> <!-- Add your other nav elements (links, menus, etc.) here --> </nav>
Pro tip: If you plan to use user-generated HTML in titles later, add a sanitization step (like DOMPurify) to avoid XSS risks—this is safe for trusted content you control.
Routify gives every page access to a pageContext object that's shared with the parent layout. Export this from each child page to define custom nav titles:
Login.svelte (plain text title)
<!-- Login.svelte --> <script> export let pageContext = { navTitle: "Sign In to Your Account" }; </script> <!-- Your login form content here -->
Article.svelte (plain text title)
<!-- Article.svelte --> <script> export let pageContext = { navTitle: "Latest Tech Articles" }; </script> <!-- Article list/content here -->
User.svelte (HTML-rich title)
<!-- User.svelte --> <script> export let pageContext = { // Include HTML for styled titles navTitle: `<span class="text-accent">User Profile</span> <small>@jane_doe</small>` }; </script> <!-- User profile content here -->
Comment.svelte (plain text title)
<!-- Comment.svelte --> <script> export let pageContext = { navTitle: "Join the Discussion" }; </script> <!-- Comment section content here -->
In your _layout.svelte, import Routify's page store to access the active page's context, then pass the title to the Nav component. Fall back to the default if no page-specific title exists:
<!-- _layout.svelte --> <script> import { page } from "@roxi/routify"; import Nav from "./Nav.svelte"; </script> <!-- Pass the page's nav title, or use the default --> <Nav navTitle={$page.context.navTitle || "MyApp"} /> <!-- Routify's outlet for rendering child pages --> <slot />
If you need to set titles dynamically (e.g., after fetching data from an API), just update the pageContext object in your page component. Routify's reactivity will automatically update the Nav title:
<!-- Example: Async title from API --> <script> export let pageContext = {}; async function loadUserProfile() { const res = await fetch("/api/user/profile"); const user = await res.json(); // Update the nav title dynamically pageContext.navTitle = `<span class="text-accent">${user.name}</span> <small>@${user.username}</small>`; } // Run on page load loadUserProfile(); </script>
- Automatic Page Transition Updates: Routify's
$pagestore reacts instantly to navigation changes, so the nav title will update without page reloads—perfect for SPAs. - Extensible Props: Want to add more nav features (like breadcrumbs or a back button)? Just extend the
pageContextobject in pages and add corresponding props toNav.svelte. - Global Overrides: If you need a global title fallback (e.g., user-customized app names), combine this with a Svelte store that takes priority over page context and defaults.
内容的提问来源于stack exchange,提问作者user2670914

