最近项目中使用了vue-router的addRoutes这个api,遇到了一个小坑,记录总结一下。

场景复现:

做前端开发的同学,大多都遇到过这种需求:页面菜单根据用户权限动态生成,一个常见的解决方案是:

前端初始化的时候,只挂载不需要权限路由,如登陆,注册等页面路由,然后等用户登录之后,后端返回当前用户的权限表,前端根据这个权限表遍历前端路由表,动态生成用户权限路由,然后使用vue-router提供的addRoutes,将权限路由表动态添加到路由实例中,整个过程大致如下:

// router.js 文件// 需要用户权限的路由表
const appRoutes = [{path: '/dashboard',name: 'dashboard',component: () => import('...'),children: [RouteConfig1,RouteConfig2,...]},RouteConfig,...
];// 不需要用户权限的路由表
const constantRoutes = [{path: '/login',name: 'login',component: Login},{path: '/register',name: 'register',component: Register},...
]// 初始化路由的时候,只挂载不需要用户权限的路由表
const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,constantRoutes
});/**** 假如后端返回的数据格式如下:** {* status: 200,* message: 'successful',* data: {*  user: {...},*  token: '...',*  permisssion: [...]* }* }** login.vue*/
axios.post('/user/login',{username,password}).then(res => {if (res.status === 200) {// 如果登录成功,则需要遍历生成用户权限路由// filterRoutes根据permission和router.js中定义的appRoutes生成动态路由表const routes = filterRoutes(permission);// 然后使用addRoutes将routes挂载到router中router.addRoutes(routes);} else {...}}).catch(error => { ... })

写到这里,貌似动态生成路由的功能就好了,一切都perfect了,但问题紧接着就来了,当用户登录之后,我们点击页面上的退出按钮退出当前登录,然后重新登录,会发现浏览器console面板紧接着就报如下错误:

纳尼(⊙o⊙)?这是怎么回事呢,第二次登录也正常登录了,功能上似乎没有什么问题,但这个警告从哪里来的呢?对于一个重度强迫症患者来说,任何警告和报错都是不允许出现的,哪怕功能上没什么问题。

捋一捋

这段警告的意思是说,以上的这几个路由命名重复,存在多个name相同的路由。那么为什么会有多个路由名称相同的路由呢?

让我们从头捋一下这个错误是怎么来的。首先第一次打开网站登录的时候是没有问题的,只有当我们退出登录,重新登录的时候,这段警告就来了。并且如果我们在重复登录之前刷新一下浏览器然后再登录,这种警告就不会出现了,很神奇是不是?

分析一下上面的情景:首先这个警告只会在用户重新登录的时候出现,登录的时候我们做的唯一跟路由相关的事情就是动态添加路由,所以问题肯定出在 router.addRoutes(routes)这里,其次这里又分了两种情况:有刷新和无刷新。在无刷新的情况下会报这个警告,有刷新就不会报这个警告。那么有刷新和无刷新有什么区别呢?

我们很容易就想到,当页面刷新的时候,Vue实例会重新初始化,Vue实例初始化的过程中,挂载在它上面的Vue-Router,Store等内容也会重新初始化。而在不刷新的情况下,就不会重新初始化。

再想想,我们第一次登录之后,通过addRoutes添加了权限路由routes到router上,假设我们这个权限routes中包括了dashboard,user,role三个路由,那么当我们退出登录,然后重新登录的时候,由于同一个用户登录,后端返回的权限列表是一样的,生成的动态路由routes也是一样的(即里面同样包含了dashboard,user,role三个路由),那么此时再次添加这三个路由就导致router中挂载的routes重复。而在刷新的情况下,由于router重新初始化,只包含了初始化我们添加的不需要权限的路由,此时再次登录,重新添加就不存在路由重复的问题了。

通过以上的分析,我们搞清了问题的来源,那么如何解决呢,很遗憾,vue-router并没有删除路由的api。根据以上的分析,我们很容易想到,通过强制刷新页面的方式来重置router:即当用户退出登录的时候,通过js强制刷新一下页面。就可以解决问题。这种方式虽然可以解决问题,但显得不是很优雅,而且刷新页面导致资源重新加载和页面闪烁,体验也不是特别好。因此有没有在不刷新的情况下解决问题的办法呢?

经过一番搜索,终于找到了一种方法,即重置当前router的match属性:

router.js

// 定义一个函数来创建router
export const createRouter = routes => new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
});// 在使用addRoutes的地方
// 重置当前router的match = 初始router.match
router.match = createRouter(constantRoutes).match;
router.addRoutes(routes);

这样就可以完美解决问题了。

总结:

整个解决的过程还是比较痛苦的,因为实际中我的代码是比较复杂的,并不像上面简化后那么简单。

整个addRoutes是在store.dispatch中完成,并且中间还夹杂着生成动态路由,根据动态路由再生成用户菜单等一系列功能,干扰比较大,并且这个是源码报警,不好定位,只能通过console和浏览器调试,一步步缩小报错范围,最终找到问题原因。

然后再通过google,以及搜索vue-router仓库的issue一步步找到解决方法。

所以想说,如果大家开发中遇到一些第三方依赖的问题,可以去搜索官方仓库的issue,很好用的,很多问题其实issue中都有答案。我是屡试不爽。

最后,一定要用google,百度,浪费我好长时间,啥都没找到~

vue-router之解决addRoutes使用遇到的坑相关推荐

  1. 已解决vue-router4路由报“[Vue Router warn]: No match found for location with path“

    vue-router4动态加载的模式下,当我们在当前页面刷新浏览器时,会出现一个警告 [Vue Router warn]: No match found for location with path ...

  2. vue router连续点击多次路由报错根本原因和解决方法

    原因: vue-router 升级到 3.1.x 后,重复点击导航时,控制台出现报错 ,vue router ≥ v3.1 后 ,回调形式改成 promise api 了,返回的是 promise,如 ...

  3. addroutes刷新_vue 解决addRoutes动态添加路由后刷新失效问题

    前言 某些场景下我们需要利用addRoutes动态添加路由,但是刷新后就会失效,前段时间项目里刚好遇到了这个应用场景,所以就花时间研究了一下,做下分享跟记录,说的不对的地方,请大家指正. 应用场景:用 ...

  4. addroutes刷新_vue解决addRoutes多次添加路由重复的操作方法

    本篇文章小编给大家分享一下vue解决addRoutes多次添加路由重复的操作方法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 代码如下: impor ...

  5. Vue + Nodejs + Express 解决跨域的问题

    Vue + Nodejs + Express 解决跨域的问题 首先检测你的Vue的版本号 此文章针对3.0版本解决跨域问题 $ vue -V 2.X or 3.X 直接访问如下 created() { ...

  6. Vue中路由管理器Vue Router使用介绍(三)

    2019独角兽企业重金招聘Python工程师标准>>> 一.路由定义添加动态参数定义 1.路由定义项,使用:xx 方式 定义动态参数 {path:'/user/:id/:name', ...

  7. [Vue Router warn]: Component “default“ in record with path “/xx“ is a function that does not return

    [debug日记] [Vue Router warn]: Component "default" in record with path "/xxx" is a ...

  8. Vue Router 实现路由控制实战

    本文是我在学习过程中记录学习的点点滴滴,目的是为了学完之后巩固一下顺便也和大家分享一下,日后忘记了也可以方便快速的复习. Vue Router 实现路由控制实战 前言 一.什么是单页面应用及实现前端路 ...

  9. vue 什么是渐进式 响应式 意思。Vue常用的指令。VUE:跨域设置。vue router 新窗口。$router.push。

    Vue  是 轻量的 模型视图视图模型 框架.就是数据的双向开发. 数据驱动+组件化开发. 渐进式框架. 官网:cn.vuejs.org 在读 Vue2.0 文档的时候,介绍"Vue.js( ...

最新文章

  1. ML基础 : 训练集,验证集,测试集关系及划分 Relation and Devision among training set, validation set and testing set...
  2. andengine的convertLocalCoordinatesToSceneCoordinates方法
  3. 数据结构 - 静态单链表的实行(C语言)
  4. 【Spring注解系列08】@PostConstruct与@PreDestroy
  5. 多线程编程学习笔记——任务并行库(三)
  6. python单元测试的应用_单元测试pythongui应用程序的推荐方法是什么?
  7. max std value 宏_【转载】:【C++跨平台系列】解决STL的max()与numeric_limits::max()和VC6 min/max 宏冲突问题...
  8. Python学习日记之忽略删除字符串空白
  9. 计算机主机结构3维图,台式主机内部结构图,主机结构图
  10. java 微服务 dubbo_Dubbo Spring Cloud 重塑微服务治理
  11. 树莓派+SAKS扩展板实现数码管时钟
  12. 多益网络社招iq_多益网络2018秋招iq测试题(二)
  13. Python爬取煎蛋网多页的图片
  14. 校园卡水卡最低成本破解具体过程(补上上次工具教程)By:dj1149 -02
  15. 欢迎来到yoeodeity yoeo耀月
  16. JavaScript--JavaScript和web API、JS(提供案例)
  17. 字节跳动 CEO 张一鸣炮轰 HR , “按这要求我自己都进不来!”
  18. 家庭版安装DotNetFX35
  19. 上海地铁和北京地铁_地铁介绍
  20. UIPATH 数据提取

热门文章

  1. ITSM01---自动化运维环境搭建
  2. java计算机毕业设计家教到家平台MyBatis+系统+LW文档+源码+调试部署
  3. arm蜂鸣器程序 linux_Linux 下控制蜂鸣器发声的程序
  4. 2022-10-09 mysql列存储引擎-exists结果错误-问题分析
  5. Android样式之view animation
  6. SSD中,SATA、m2、PCIE和NVME各有什么意义
  7. undefined reference to `__isoc99_sscanf‘
  8. Angular CLI ng常用命令整理
  9. 使用HBuilder将H5的项目打包成手机可安装的webapp程序(.apk)
  10. com.mysql.jdbc.PacketTooBigException: Packet for query is too large 异常解决办法