阴间BUG之动态路由添加失败
0. BUG直通车
Duplicate named routes definition
错误原因:路由中有重复的名称。
1. 路由缓存的锅
vue-router动态添加路由的方法,addRouter添加路由,提示:Duplicate named routes definition-Bug收集 - Bug搜集 (bugshouji.com)
router.matcher = new Router({ mode: 'history' }).matcher;
asyncRouters(state.routers).forEach(item => {
router.addRoute(item)
})
// router.addRoutes(asyncRouters(state.routers))
下面注释的代码行是先前获取路由的addRoutes方法,正如参考文章所说,addRoutes并没有删除之前存在的路由,只是注入新路由。因此,在添加新路由之前,得给路由匹配区清空一下,
2. 路由匹配区Matcher
Vue Router 的 matcher 实现了一些非常重要的API:
- match() 根据传入的路由和当前的路由计算出新的路由。
- addRoutes() 可以动态添加更多的路由规则。已废弃:官方建议使用 router.addRoute() 代替。
- addRoute() 添加一条新的路由规则。
- getRoutes() 获取所有活跃的路由记录列表。
使用router-link可以实现跳转到指定路由界面,但是我们如何知道哪个 URL 对应的 View 的具体内容是什么呢? 换句话说就是如何将 URL 与 View 关联起来呢?即建立 URL 与 View 的映射关系。如果我们知道了这个对应关系,那么在 URL 变化的时候我们只需要更新对应的视图内容就可以了。这就是 matcher.match 的作用啦!
3. 何时获取匹配的路由地址
import { asyncRouters } from "utils/utils";
这个方法是通过后台发送的信息,转化为router格式再添加。
// 异步路由加载
export function asyncRouters(routers) {
let staticRouter = ['test']
return routers.map(item => {
if (staticRouter.includes(item.router)) {
let route = routes.find(ele => ele.path.indexOf(item.router) !== -1);
return route
} else {
return {
path: `/${item.router}`,
name: item.router.toUpperCase(),
component: () => import('../views/Home'),
meta: {
alias: item.alias // 路由名称
},
}
}
}).filter(it=>it)
}
4. 使用添加的动态路由
// 在home页面中加入动态路由
<router-link
:class="[$route.path.includes(item.path) ? 'is-router-active' : '']"
:to="item.path"
tag="a"
v-for="(item, index) in buttons"
:key="index"
>{{ item.name }}
</router-link>
// ...
computed: {
routers: {
get() {
return this.$store.state.routers;
},
},
buttons: {
get() {
// 路由过滤,默认路由不可替代
let rs = this.routers
.map((item) => {
return {
name: item.menuName,
path: `/${item.router}`,
};
})
.filter((it) => it);
return rs;
},
},
}
// style
.is-router-active {
background: url("bg.png") no-repeat;
background-size: 100% 100%;
}
人生到处知何似,应似飞鸿踏雪泥。