You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js动态添加子路由及addRoutes API用法求助

嘿,这个需求我之前也碰到过,其实用Vue Router的API就能轻松实现“父路由访问时才动态添加子路由+模块懒加载”的效果,我给你一步步拆解:

核心思路

利用路由的**beforeEnter守卫**(或者父组件的生命周期钩子),在父路由第一次被访问时,动态加载子路由的配置模块,再通过addRoutes(Vue2)/addRoute(Vue3)把这些子路由挂载到父路由下,同时子路由的组件也可以用懒加载方式引入,实现模块按需加载。

具体实现步骤(以Vue2 + Vue Router 3.x为例)

1. 先定义基础父路由

先在路由初始化时只定义父路由,暂时不配置children(或者留空数组):

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter({
  routes: [
    {
      path: '/parent',
      name: 'Parent',
      // 父组件也可以懒加载
      component: () => import('./views/Parent.vue'),
      children: [] // 先留空,后续动态添加
    }
  ]
})

export default router

2. 单独定义子路由配置文件

把子路由的配置抽成单独的文件(比如./routes/childRoutes.js),方便维护,而且子组件也用懒加载:

// ./routes/childRoutes.js
export default [
  {
    path: 'child1', // 相对父路由的路径,最终会拼成/parent/child1
    name: 'Child1',
    component: () => import('../views/Child1.vue')
  },
  {
    path: 'child2',
    name: 'Child2',
    component: () => import('../views/Child2.vue')
  }
]

3. 在父路由的beforeEnter守卫中动态添加子路由

修改父路由的配置,加入beforeEnter守卫,在第一次访问时加载子路由并添加:

// 新增一个标记,避免重复添加路由
let isChildRoutesAdded = false

const router = new VueRouter({
  routes: [
    {
      path: '/parent',
      name: 'Parent',
      component: () => import('./views/Parent.vue'),
      children: [],
      beforeEnter: async (to, from, next) => {
        if (!isChildRoutesAdded) {
          // 动态加载子路由配置模块
          const childRoutes = await import('./routes/childRoutes.js')
          // 把子路由添加到父路由下
          router.addRoutes([
            {
              path: '/parent',
              children: childRoutes.default
            }
          ])
          isChildRoutesAdded = true
          // 如果当前访问的是子路由(比如直接输入/parent/child1),需要重新导航一次确保路由匹配生效
          next(to.fullPath)
        } else {
          next()
        }
      }
    }
  ]
})

(可选)在父组件中实现动态添加

如果不想用路由守卫,也可以在父组件的beforeMount钩子中做同样的操作:

<!-- Parent.vue -->
<template>
  <div>
    <h1>父组件</h1>
    <router-view></router-view>
  </div>
</template>

<script>
let isChildRoutesAdded = false

export default {
  async beforeMount() {
    if (!isChildRoutesAdded) {
      const childRoutes = await import('../routes/childRoutes.js')
      this.$router.addRoutes([
        {
          path: '/parent',
          children: childRoutes.default
        }
      ])
      isChildRoutesAdded = true
    }
  }
}
</script>
Vue3 + Vue Router 4.x的差异

如果是Vue3项目,API有一点变化:

  • 用router.addRoute()(单数)替代addRoutes()
  • 添加子路由时可以直接指定父路由的name,更简洁:
// 在beforeEnter中
const childRoutes = await import('./routes/childRoutes.js')
childRoutes.default.forEach(route => {
  router.addRoute('Parent', route) // 'Parent'是父路由的name
})
关键注意事项
  • 避免重复添加:一定要加标记变量(比如isChildRoutesAdded),不然每次访问父路由都会重复添加路由,导致路由表冗余。
  • 子路由导航生效:如果用户直接访问子路由(比如/parent/child1),第一次触发守卫时路由还没添加,所以需要调用next(to.fullPath)重新导航,确保路由能正确匹配。
  • 模块懒加载:不管父组件还是子组件,都用() => import()的方式引入,真正实现按需加载,减小初始包体积。

内容的提问来源于stack exchange,提问作者Nexus23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:42:40