SvelteKit组件路由配置:实现settings子路径URL显示需求
SvelteKit 实现 Settings 页面嵌套路由方案
核心思路
放弃哈希切换,改用SvelteKit 嵌套路由实现,这样既可以得到 settings/users 这类规范 URL,又能给每个子页面配置独立的 +page.server.js 处理服务端逻辑。
方案一:独立子路由(推荐,逻辑清晰)
1. 重构路由结构
按以下目录结构创建文件:
src/routes/ ├─ settings/ │ ├─ +layout.svelte # 父布局:左侧导航 + 右侧内容出口 │ ├─ +page.server.js # 可选:访问 /settings 时重定向到默认子页面 │ ├─ users/ │ │ ├─ +page.svelte # Users 内容页 │ │ └─ +page.server.js # Users 专属服务端逻辑 │ ├─ create/ │ │ ├─ +page.svelte # Create 内容页 │ │ └─ +page.server.js # Create 专属服务端逻辑 │ └─ coins/ │ ├─ +page.svelte # Coins 内容页 │ └─ +page.server.js # Coins 专属服务端逻辑
2. 父布局(settings/+layout.svelte)
负责渲染左侧导航,右侧用 <slot /> 加载子页面内容:
<script> import { page } from '$app/stores'; // 导航配置 const navItems = [ { path: '/settings/users', label: 'users' }, { path: '/settings/create', label: 'create' }, { path: '/settings/coins', label: 'coins' } ]; </script> <div class="settings-wrapper"> <!-- 左侧迷你导航 --> <nav class="mini-nav"> {#each navItems as item} <a href={item.path} class:active={$page.url.pathname === item.path} > {item.label} </a> {/each} </nav> <!-- 右侧内容区域 --> <main class="content"> <slot /> </main> </div> <style> .settings-wrapper { display: flex; gap: 2rem; padding: 1rem; } .mini-nav a { display: block; padding: 0.6rem 1.2rem; margin: 0.4rem 0; text-decoration: none; border-radius: 4px; } .mini-nav a.active { font-weight: bold; background-color: #e6f0ff; color: #0066cc; } </style>
3. 子页面与服务端逻辑
以 Users 页面为例:
settings/users/+page.server.js:
export async function load() { // 这里写专属服务端逻辑,比如拉取用户列表 const users = await fetch('https://api.example.com/users').then(res => res.json()); return { users }; }
settings/users/+page.svelte:
<script> export let data; </script> <h2>用户管理</h2> <ul> {#each data.users as user} <li>{user.name} - {user.email}</li> {/each} </ul>
4. 默认路由重定向(可选)
如果希望访问 /settings 时自动跳转到 /settings/users,在 settings/+page.server.js 中添加:
export function load({ redirect }) { return redirect(302, '/settings/users'); }
方案二:动态 Slug 路由(适合逻辑相似的页面)
如果不想创建多个子文件夹,可以用动态路由参数实现:
1. 路由结构
src/routes/ ├─ settings/ │ ├─ +layout.svelte # 父布局同方案一 │ ├─ +page.server.js # 可选:重定向到默认 slug │ └─ [section]/ │ ├─ +page.svelte # 根据 section 参数渲染对应内容 │ └─ +page.server.js # 根据 section 参数处理不同服务端逻辑
2. 动态路由的服务端逻辑([section]/+page.server.js)
export async function load({ params }) { const { section } = params; // 根据不同 section 返回对应数据 switch (section) { case 'users': const users = await fetch('https://api.example.com/users').then(res => res.json()); return { section, users }; case 'create': return { section, defaultFormData: { name: '', email: '' } }; case 'coins': const coins = await fetch('https://api.example.com/coins').then(res => res.json()); return { section, coins }; default: throw error(404, 'Section not found'); } }
3. 动态路由的页面渲染([section]/+page.svelte)
<script> export let data; </script> {#if data.section === 'users'} <h2>用户列表</h2> <ul>{#each data.users as user}<li>{user.name}</li>{/each}</ul> {:else if data.section === 'create'} <h2>创建用户</h2> <form> <input type="text" placeholder="用户名" value={data.defaultFormData.name} /> <input type="email" placeholder="邮箱" value={data.defaultFormData.email} /> <button type="submit">提交</button> </form> {:else if data.section === 'coins'} <h2>金币管理</h2> <p>当前金币总数:{data.coins.total}</p> {/if}
内容的提问来源于stack exchange,提问作者m40ma0
相关产品推荐
相关产品推荐

