陰間BUG之動態路由新增失敗
阿新 • • 發佈:2021-12-20
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%;
}
人生到處知何似,應似飛鴻踏雪泥。