使用addRoute加载动态路由时,刷新页面后出现空白页和控制台报错

1,297 阅读2分钟

1.问题描述

【vue-router 4.x】使用addRoute加载动态路由时,刷新页面后出现空白页和控制台警告[Vue Router warn]: No match found for location with path "/child-vite?vite-child=%2Fabout"

2.项目背景

项目的菜单是根据后端接口动态返回的,参照ant-design-pro的动态菜单设计

项目使用的是vue3+vue-router4.x + vite搭建的

"vite": "^4.0.0",

"vue-router": "^4.1.6"

permission.js中如下: image.png

现在是可以正常运行的(刷新后页面路由可以正常展示,虽然警告还在),是因为将之前的next()修改成下面这样的了。

image.png

3.问题分析

  • 通过router.getRoutes()打印routes发现路由表在初始化进入和刷新页面没有差别

aliasof undefined.png

  • 在router.beforeEach中log to的值,发现不一样了

直接跳转

image.png

刷新

permission.jst=168145059153520.png

总结:这个问题其实困扰了蛮久的,开始以为是不是刷新后路由没有生成,所以去对比,但是发现没有问题。还以为是不是addRoute方法使用有问题,但是初始化却可以呀。没有考虑到next这一方面。

3.next()和next('/login')的区别

next() 是放行,但是如果next()里有参数的话,next()就像被重载一样,就有了不同的功能。

next('/login')不是说直接去/login路由,而是中断(不是CPU的那个中断!VUE中的中断就是此时不会执行router.afterEach(() => {})这一次路由守卫的操作,又进入一次路由守卫,就像嵌套一样,一层路由守卫,然后又是一层路由守卫,此时路由守卫进入到第二层时,to.path已经不是/home了,这个时候才执行next()放行操作。

如果next参数是一个字符串,比如 ,这样可以在login页面正确获取redirect参数

next(`/login?redirect=${to.fullPath}`)

但是如果参数是一个对象,比如

  next({
      path: `/login?redirect=${to.fullPath}`,
      replace: true,
    })  

这样是无法在login页面获取redirect参数的,正确写法是

 next({
     path: `/login`,
     query: { ...to.query, redirect: to.fullPath },
     replace: true,
   });

参考文章1 参考文章2