技术选择
· VUE3
· VUE-ROUTER@4
问题发现
· 路由表分为 静态路由 和 动态路由 ,动态路由在 路由守卫 中判断用户登录后请求的 菜单权限 进行 动态添加
· 在 动态路由路径页面 中刷新浏览器时会导致控制台 报出警告 ,但是页面可以正常跳转
// 动态添加路由的判断逻辑,如果没有菜单列表,就要重新请求菜单列表并添加动态路由
const authStore = useAuthStore() // 用户的权限仓库
if(!authStore.authRouterList.length) { // 用户权限仓库为空说明还没有鉴权添加动态路由
await initDynamicRouter() // 此处方法为判断动态路由表和用户权限从而添加路由
return next({...to, replace: true}) // 中断此次跳转并携带此次跳转的所有信息重新进入路由
}
问题逐步解决
Q 首先刷新浏览器后报出警告,发现页面 初次进入 时,守卫拦截到的 to 路由信息中匹配到的路由为空(hash路由方式)
[Vue Router warn]: No match found for location with path "/acl/user"
{
"fullPath": "/acl/user",
"path": "/acl/user",
"query": {},
"hash": "",
"params": {},
"matched": [], // 匹配为空
"meta": {},
"href": "#/acl/user"
}
A 在 静态路由表 中添加 全匹配路由 (注意全匹配写法),这样第一次路由表中不存在该 路由(动态路由) 时也能匹配到一个路由
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
meta: {
isHide: true
},
component: () => import("@/views/error/error-404.vue")
},
Q 再次刷新尝试发现控制台 警告消失,但是路由俩次跳转 (第一次因为 鉴权添加动态路 由被打断),发现应用仍然会停留在 404页面
查看打印的俩次 to 路由找寻答案(俩次打印除了 redirectedFrom 属性外一模一样)
{
"fullPath": "/acl/user",
"path": "/acl/user",
"query": {},
"hash": "",
"name": "NotFound",
"params": {
"pathMatch": [
"acl",
"user"
]
},
"matched": [
{
"path": "/:pathMatch(.*)*",
"name": "NotFound",
...
}
],
"meta": {
"isHide": true
},
"href": "#/acl/user"
}
A 发现仅仅只有一个 redirectedFrom 属性不同,第一个 to 路由中该属性为 undefined,第二个 to 路由中该属性为第一个 to 路由对象
再细看发现匹配的居然都是 NotFound,而在俩次 to 路由中的 name 属性也都是 undefined
( 这里我感觉是不是 to 中携带的 name 属性优先级高于 path 属性,导致 第二次匹配 的时候直接识别了 name 属性去匹配了 NotFound 路由 )
在鉴权打断的 next 方法中 {...to} 是期望路由器 携带所有路由信息 进入 动态路由添加完毕 之后的路由表匹配,直接对
return next({...to, replace: true}) // 中断此次跳转并携带此次跳转的所有信息重新进入路由
修改成
return next({path: to.fullPath, replace: true})
可能导致携带的 路由信息 丢失!!
解决方案一
判断 name 进行修改
const authStore = useAuthStore()
console.log(to)
if(!authStore.authRouterList.length) {
await initDynamicRouter()
if(to.name == "NotFound") { // 添加判断条件
to.name = ""
}
return next({...to, replace: true})
}
解决方案二
直接去掉 全匹配路由 中的 name 属性就行啦(我一开始用方案一还 *沾沾自喜* 😂)
{
path: '/:pathMatch(.*)*',
// name: 'NotFound', // 直接去掉
meta: {
isHide: true
},
component: () => import("@/views/error/error-404.vue")
},
写在后面:上班......