解决动态添加路由 出现重复路由问题

2,592 阅读1分钟

在做后台管理项目时,需要根据用户权限动态添加路由,但退出登录账号1,登录账号2时,出现了[vue-router] Duplicate named routes definition这样的警告,如图:

8bb14b65064e711668b1d4eb695d963.png

Duplicate named routes definition:重复定义路由

查阅资料,这一篇文章给出了两种解决方案:
解决$router.addRoutes()添加路由,出现的路由重复添加问题

方法1:location.reload(),vue上的所有实例在刷新的时候都会被重置
方法2:刷新时只重置路由

显然,方法1所有都被重置,比较耗时,对用户不太友好,只重置路由似乎是个更好的选择
文章里给出方法2的解决方案是定义一个重置路由的函数,再在退出登录时调用即可

于是,采取方法2开始解决问题
因为涉及路由的定义,重置函数应该写在router文件夹下的index.js里

//定义新建路由方法
const createRouter = () =>
  new Router({
    mode: "history",
    routes: routes //传入定义的路由参数
  });
//新建路由
const router = createRouter()
//重置路由函数 export
export function resetRouter() {
    const newRouter = createRouter(); 
    router.matcher = newRouter.matcher; //替换成新的空路由
  }

export default router

router.matcher是比较核心的一个属性,修改了matcher即新的routes生效
对外提供两个方法match(负责route匹配), addRoutes(动态添加路由)

具体过程:在做路径切换transitionTo方法中,首先就会使用const route = this.router.match(location, this.current)来匹配route, 其实内部会使用matcher来做匹配。修改了matcher即新的routes生效。

match (
    raw: RawLocation,
    current?: Route,
    redirectedFrom?: Location
  ): Route {
    // 这里使用matcher的match方法来做匹配
    return this.matcher.match(raw, current, redirectedFrom)
  }

对router.matcher属性做修改,即新的routes就会替换老的routes, 其实就是replaceRoutes()的含义(但是官方没有提供这个API)。

export type Matcher = {
  match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route;
  addRoutes: (routes: Array<RouteConfig>) => void;
};

接下来,就是在退出登录按键下调用这个resetRouter函数
退出登录在CommonHeader.vue的下拉菜单里
首先在CommonHeader.vue里引入resetRouter函数

import {resetRouter} from '../router/index'

然后在按键绑定的方法里调用即可

 handleCommand(command){
            if(command === 'logout'){
                Cookie.remove('token')
                Cookie.remove('menu')
                this.$router.push('/login')
                resetRouter()    //重置路由           
            }
        }

再次运行项目就没有警告了,问题解决!

参考资料(vue.js - vue-router工作原理概述和问题分析)