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中如下:
现在是可以正常运行的(刷新后页面路由可以正常展示,虽然警告还在),是因为将之前的next()修改成下面这样的了。
3.问题分析
- 通过router.getRoutes()打印routes发现路由表在初始化进入和刷新页面没有差别
- 在router.beforeEach中log to的值,发现不一样了
直接跳转
刷新
-
解决,也是 百度了一下
总结:这个问题其实困扰了蛮久的,开始以为是不是刷新后路由没有生成,所以去对比,但是发现没有问题。还以为是不是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,
});