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
相关产品推荐
相关产品推荐

