beforeEach中addRoutes后使用next()无法访问,路由未生效,刷新页面白屏,使用next({ ...to, replace: true })
查看路由表和匹配结果的方法
使用getRoutes()
方法查看addroutes
前后的路由表
使用to.matched
查看匹配的路由
(vue router版本>=3.5.0)
问题描述:
使用addRoutes
动态添加路由后,直接使用next()
,无法访问路由,白屏。
输入日志分析:
问题分析
问题的关键在于遍历路由表的时机,由于对to的路由匹配结果在进入beforeEach之前就已经完成,使用的是addRoutes之前的路由表,匹配结果为空,并且在接下来的流程中匹配结果不变,执行next()时,放行的是空路由,导致白屏。
错误说法:
网上有说法称,addRoutes
是异步执行,立刻执行next()
时addRoutes
还未执行完毕,所以找不到路由,这是完全错误的。addRoutes
表示我不背这个锅,你不重新遍历路由表怪谁。
因为我们在console中输出的日志,可以清晰的看到,在next()
开始执行之前,路由表已经添加完毕并打印出来了,但是匹配结果仍然不变,因为又没有重新匹配,无论你等多长时间,也不会改变。
还有说是因为路由没生效,也不对,路由当时就添加进去了,添加进去就可用了,没有生不生效这一说。
问题解决
addRoutes
后,不要使用next()
,使用next(to)
,重新使用新的路由表进行匹配。
不过要注意,next(to)
会再次进入beforeEach
路由守卫,我们要设置判断逻辑,如果路由信息已经存在,就不再执行addRoutes
,直接next()
放行,才能跳转成功。不然会一直next(to)
,循环进入beforEach
。
同时,我们不希望之后每次刷新同一个页面,都重复插入相同的路由历史记录,可以加一个选项replace: true
,使用替换模式来替换最新一条相同历史记录
if(路由信息已添加){
// 直接放行
next()
}
else{
//添加动态路由信息
addRoutes(xxx)
//手动重新使用新路由表匹配目标
next({ ...to, replace: true })
}
查看console
日志,当再次进入beforeEach
,我们可以看到使用的是新路由表,匹配结果不为空了。并且这次已经有用户路由信息了,直接next()
放行