阴间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 的作用啦!

手写Vue Router源码系列二:实现 matcher - 掘金 (juejin.cn)

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%;
        }
posted @ 2021-12-20 11:15  乐盘游  阅读(632)  评论(0编辑  收藏  举报