命名路由与命名视图
直接使用路径字符串进行导航虽然简单直观,但在路由路径发生变化时,所有引用该路径的地方都需要手动修改。命名路由通过给路由指定唯一名称,让你可以通过名称而非路径来引用路由,从而解耦导航逻辑与路径结构。命名视图则允许在同一路由中渲染多个组件,适用于复杂的页面布局。
命名路由
定义命名路由
通过 name 字段为路由指定名称:
ts
const routes = defineRoutes(
{ path: '/user/{id}', name: 'user', component: UserProfile },
{ path: '/settings', name: 'settings', component: Settings }
)通过名称导航
使用名称导航时,通过 index 字段指定路由名称,并通过 params 传递动态参数:
ts
import { useRouter } from 'vitarx-router'
function SomeComponent() {
const router = useRouter()
function goToUser() {
router.push({
index: 'user',
params: { id: '123' }
})
}
return <button onClick={goToUser}>查看用户</button>
}在模板中,RouterLink 同样支持名称导航:
tsx
<RouterLink to={{ index: 'user', params: { id: '123' } }}>查看用户</RouterLink>WARNING
路由名称不能以 / 开头。以 / 开头的字符串会被识别为路径而非名称:
ts
// ❌ 错误:以 / 开头会被当作路径
{ path: '/user/{id}', name: '/user', component: UserProfile }
// ✅ 正确:名称不以 / 开头
{ path: '/user/{id}', name: 'user', component: UserProfile }名称导航失败
当通过名称导航时,如果指定的名称不存在或参数校验失败,路由器会抛出错误。这是因为名称导航属于编程式调用,名称不存在或参数不匹配通常意味着代码存在 bug。
ts
// 名称不存在——抛出错误
router.push({ index: 'non-existent' })
// 参数校验失败——抛出错误(路由定义了 pattern 但传入的值不匹配)
router.push({ index: 'user', params: { id: 'abc' } })
// 如果 pattern: { id: /^d+$/ },则 'abc' 不匹配命名视图
定义命名视图
当页面需要同时渲染多个区域(如主内容区和侧边栏)时,可以将 component 定义为对象形式,键为视图名称,值为对应组件:
ts
const routes = defineRoutes({
path: '/dashboard',
component: {
default: DashboardMain,
sidebar: DashboardSidebar
}
})WARNING
命名视图对象必须包含 default 键,它指定了默认视图的组件。缺少 default 会导致类型错误。
ts
// ❌ 错误:缺少 default 键
{ component: { sidebar: Sidebar } }
// ✅ 正确:包含 default 键
{ component: { default: Main, sidebar: Sidebar } }渲染命名视图
使用 RouterView 的 name 属性指定要渲染的视图:
tsx
function App() {
return (
<div class="layout">
<main class="content">
{/* 渲染 default 视图 */}
<RouterView />
</main>
<aside class="sidebar">
{/* 渲染 sidebar 视图 */}
<RouterView name="sidebar" />
</aside>
</div>
)
}不指定 name 时,RouterView 默认渲染 default 视图。
完整示例
tsx
import { createRouter, defineRoutes, RouterView, RouterLink, useRouter } from 'vitarx-router'
import { createApp } from 'vitarx'
function DashboardMain() {
return <h2>仪表盘主内容</h2>
}
function DashboardSidebar() {
return (
<nav>
<RouterLink to="/dashboard">概览</RouterLink>
<RouterLink to={{ index: 'settings' }}>设置</RouterLink>
</nav>
)
}
function UserProfile() {
const router = useRouter()
return (
<div>
<h2>用户详情</h2>
<button onClick={() => router.push({ index: 'settings' })}>前往设置</button>
</div>
)
}
function Settings() {
return <h2>系统设置</h2>
}
const routes = defineRoutes(
{
path: '/dashboard',
component: {
default: DashboardMain,
sidebar: DashboardSidebar
}
},
{ path: '/user/{id}', name: 'user', component: UserProfile },
{ path: '/settings', name: 'settings', component: Settings }
)
const router = createRouter({ routes })
function App() {
return (
<div>
<RouterView />
<RouterView name="sidebar" />
</div>
)
}
createApp(App).use(router).mount('#app')