Skip to content

动态路由 | 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)
          }
        })
}

🚀 提示:动态路由为构建高度灵活和可扩展的应用程序提供了强大的工具,合理使用可以大大提升应用的可维护性和用户体验。

🚀 Vue Router - 让前端路由变得简单而强大 | 构建现代化单页应用的最佳选择