目录
文档
版本号
"vue": "2.6.10", "vue-router": "3.6.5",
有几种方式实现动态路由:
- 前端配置
完整路由
,通过接口返回的数据判断是否可显示,是否可访问 - 前端配置
部分路由
,由后端接口返回的数据生成新路由 - 抛开路由的思维,是否能直接通过
url查询参数
或者是动态路径参数
解决问题
需求
部分页面通过服务器端接口返回的参数判断是否显示
用户可以添加新的分类,分类和路由的显示方式一致,拥有和路由相同的逻辑,故而采用通过服务端返回数据生成动态路由的方式解决
实现思路
1、添加路由
通过服务端接口返回的数据生成路由,是异步返回的数据,动态添加
可以通过Vue-Router提供的api,动态添加路由数据
addRoute(parentName: string, route: RouteConfig): () => void
文档说:
如果该路由规则有 name,并且已经存在一个与之相同的名字,则会覆盖它。
我想直接覆盖原有路由,这样路由位置就不变了
实际操作的时候发现:并不会覆盖,控制台会提示路由重复
2、添加时机
应该在路由跳转之前进行
router.beforeEach(async (to, from, next) => { // 需要有一个全局变量记录是否添加过 if (!globalData.hasAddDynamicRoute) { await Store.dispatch('router/updateDynamicRoutes') globalData.hasAddDynamicRoute = true } })
3、获取路由配置
该接口获取的路由数据是一维数组,和路由配置格式不一样
// 不要使用this.$router.options.routes getRoutes(): RouteRecord[]
页面上显示的时候,需要从vuex获取路由信息,可以及时刷新页面数据
4、响应式路由
既然是动态路由,所以需要响应式,当路由数据发生变化时,可以及时的获取通知
通过vuex状态管理实现
// store/modules/router.js export default { namespaced: true, state: { routes: [], }, getters: { // 返回路由数据 getRoutes(state) { return state.routes } }, mutations: { setRoutes(state, routes) { state.routes = routes }, }, actions: { async updateDynamicRoutes({ commit }, userinfo) { // 添加动态路由 await addDynamicRoutes() // 获取完整的路由信息 const routes = router.getRoutes() commit('setRoutes', routes) }, }, }
5、路由跳转
动态路由首次跳转的时候,动态路由还没有添加,需要转换处理
// 根据 to.name 来判断是否为动态路由 if (!to.name) { // 当前路由是动态的,确定是否存在 if (router.getRoutes().findIndex((i) => i.path === to.path) !== -1) { next({ ...to, replace: true }) } else { next('/') } } else { next() }
6、路由排序
添加的路由只能在最后,无法指定插入位置
通过meta元数据,添加排序字段order_value
,可以在显示的时候实现排序
meta: { order_value: 1, },
7、更新路由
如果数据变化,需要更新路由数据,再次添加同样会提示重复
[vue-router] Duplicate named routes definition
更新前需要先重置路由数据
// src/router/index.js // 路由的创建 function createRouter() { return new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes, }) } const router = createRouter() // 重置路由 export function resetRouter() { const newRouter = createRouter() router.matcher = newRouter.matcher // reset router } export default router