动态路由 | Vue Router
什么是动态路由?
动态路由允许你在应用程序运行时动态添加或删除路由,这对于构建可扩展的应用程序(如插件系统、模块化应用)非常有用。
核心 API
Vue Router 提供了两个主要函数来处理动态路由:
router.addRoute()- 添加新路由router.removeRoute()- 删除现有路由
添加路由的基本用法
简单示例
假设我们有一个基础路由配置:
javascript
const router = createRouter({
history: createWebHistory(),
routes: [{ path: '/:articleName', component: Article }],
})这个配置会匹配所有路径(如 /about、/store),都渲染 Article 组件。
现在动态添加一个具体路由:
javascript
// 添加关于页面路由
router.addRoute({ path: '/about', component: About })
// 需要手动导航到新路由
router.replace(router.currentRoute.value.fullPath)💡 重要:添加路由后需要手动调用导航方法才能显示新页面。
异步处理
javascript
// 使用 async/await 确保导航完成
await router.addRoute({ path: '/about', component: About })
await router.replace(router.currentRoute.value.fullPath)在导航守卫中添加路由
在导航守卫中添加路由时,应该通过返回新位置来触发重定向,而不是直接调用 router.replace():
javascript
router.beforeEach(to => {
if (!hasNecessaryRoute(to)) {
// 动态生成并添加路由
router.addRoute(generateRoute(to))
// 触发重定向到新路由
return to.fullPath
}
})删除路由的三种方式
1. 通过名称冲突
添加同名路由会自动删除旧路由:
javascript
router.addRoute({ path: '/about', name: 'about', component: About })
// 同名路由会替换旧路由
router.addRoute({ path: '/other', name: 'about', component: Other })2. 使用返回的回调函数
addRoute() 返回一个删除函数:
javascript
const removeRoute = router.addRoute(routeRecord)
// 稍后删除路由
removeRoute()3. 按名称删除
javascript
router.addRoute({ path: '/about', name: 'about', component: About })
// 通过名称删除
router.removeRoute('about')🔒 安全提示:使用
Symbol作为路由名称可以避免命名冲突。
添加嵌套路由
基本嵌套
javascript
// 先添加父路由
router.addRoute({
name: 'admin',
path: '/admin',
component: Admin
})
// 然后添加子路由
router.addRoute('admin', {
path: 'settings',
component: AdminSettings
})这等价于:
javascript
router.addRoute({
name: 'admin',
path: '/admin',
component: Admin,
children: [{
path: 'settings',
component: AdminSettings
}],
})复杂嵌套结构
javascript
// 多级嵌套示例
router.addRoute({
name: 'dashboard',
path: '/dashboard',
component: Dashboard,
children: [
{ path: 'overview', component: Overview },
{ path: 'analytics', component: Analytics }
]
})
// 动态添加子路由
router.addRoute('dashboard', {
path: 'reports',
component: Reports,
children: [
{ path: 'monthly', component: MonthlyReport }
]
})路由检查功能
Vue Router 提供了两个实用的检查函数:
检查路由是否存在
javascript
if (router.hasRoute('admin')) {
console.log('管理员路由已存在')
}获取所有路由记录
javascript
const allRoutes = router.getRoutes()
console.log('当前所有路由:', allRoutes)实际应用场景
场景 1:权限动态路由
javascript
// 根据用户权限动态添加路由
function setupUserRoutes(userPermissions) {
const routes = generateRoutesBasedOnPermissions(userPermissions)
routes.forEach(route => {
if (!router.hasRoute(route.name)) {
router.addRoute(route)
}
})
}场景 2:插件系统
javascript
// 插件注册路由
function registerPlugin(pluginRoutes) {
pluginRoutes.forEach(route => {
router.addRoute(route)
})
}
// 插件卸载
function unregisterPlugin(pluginName) {
const routes = router.getRoutes()
routes.filter(route => route.meta?.plugin === pluginName)
.forEach(route => {
if (route.name) {
router.removeRoute(route.name)
}
})
}场景 3:动态菜单
javascript
// 根据后端配置生成菜单路由
async function loadDynamicMenu() {
const menuConfig = await fetchMenuConfig()
menuConfig.items.forEach(item => {
router.addRoute({
path: item.path,
component: () => import(`./views/${item.component}.vue`),
meta: { menuItem: true }
})
})
}最佳实践和注意事项
1. 错误处理
javascript
try {
router.addRoute(newRoute)
await router.replace(router.currentRoute.value.fullPath)
} catch (error) {
console.error('路由添加失败:', error)
// 回滚或显示错误信息
}2. 避免重复添加
javascript
function safeAddRoute(route) {
if (route.name && router.hasRoute(route.name)) {
console.warn(`路由 ${route.name} 已存在,跳过添加`)
return
}
router.addRoute(route)
}3. 内存管理
定期清理不再使用的路由:
javascript
function cleanupUnusedRoutes() {
const routes = router.getRoutes()
routes.filter(route => route.meta?.lastAccessed < Date.now() - 3600000)
.forEach(route => {
if (route.name) {
router.removeRoute(route.name)
}
})
}🚀 提示:动态路由为构建高度灵活和可扩展的应用程序提供了强大的工具,合理使用可以大大提升应用的可维护性和用户体验。