踩坑记16 vue-router4 动态路由 刷新404/白屏/样式错误 next css | 退出登录 removeRoute()后 router.options.routes未更新
2021.8.16坑53(vue3、vue-router4、动态路由、刷新404或白屏、next):简略版:(tips:不只刷新会出问题,输入网址导航也会)1、刷新404:将匹配全部为定义路径到404的路由从静态路由表中去除,在动态权限路由都添加了之后在添加。接下来可能会报warn并白屏,解决方法见下一条2。2、刷新白屏:如果是在路由守卫router.beforeEach中检测并用router.a
2021.8.16
坑53(vue3、vue-router4、动态路由、刷新404或白屏、next):
简略版:(tips:不只刷新会出问题,输入网址导航也会)
1、刷新404:将匹配全部为定义路径到404的路由从静态路由表中去除,在动态权限路由都添加了之后在添加。接下来可能会报warn并白屏,解决方法见下一条2。
2、刷新白屏:如果是在路由守卫router.beforeEach中检测并用router.addRoute添加的路由,则需要将动态权限路由添加后的next()放行,改为next(to)触发新导航。注意:使用next(to)相当于总共调用了两次路由导航,会触发两次router.beforeEach,其他一些相关监听,也会被调用两次,需要注意调整。
详细踩坑情况:
前情提要:之前配置静态路由的时候,将不匹配地址统一导航到了404页面,路由代码如下:
{
path: '/:pathMatch(.*)*',
redirect: '/404'
}
这导致在动态权限添加路由时,所添加的权限路由在使用地址匹配时都会被拦截导航到404页面(输入网址导航、刷新页面会,在页面中通过点击等方式直接触发的路由变化不会)。
所以将此路由从静态路由表去除,放到动态权限路由获取相关函数中,在动态权限路由添加之后添加即可。
但是,当刷新页面时,还是会报错warn,并且显示白屏:
vue-router.esm-bundler.js:72 [Vue Router warn]: No match found for location with path "/xxx/yyy"
提示表示没能匹配到相应路径,也就是说路由还没加上。查看addRoute的文档 API 参考 | Vue Router (vuejs.org),有提示"请注意,添加路由并不会触发新的导航。也就是说,除非触发新的导航,否则不会显示所添加的路由。"
而代码中router.addRoute的触发是在路由守卫router.beforeEach中检测到当前未保存(用vuex)动态菜单信息(网络请求获取)时,之后用next()放行。而根据文档提示和控制台相关打印信息可以看到,warn提示在addRoute添加路由之前,所以解决方法是将next()改为next(to),触发新的一个导航,此时可以正确匹配到动态权限路由的相应地址。
参考: VUE 路由守卫 next() / next({ ...to, replace: true }) / next(‘/‘) 说明_cimo的博客-CSDN博客
坑54(vue、css、样式错误):
问题产生:设置动态权限路由后,发现从登录页进入到内容页时,所有的内容页都会混乱,刷新可恢复正常。
原因:vue的script中的css属性会全局生效,而在使用动态路由后,前一页vue组件中的script的css属性被带到了这一页。
方法1:更改使用样式的class名,使其不与其他页面中的class名重复,比如此次导致问题产生的是container类,将其名称改为loginContainer类后,问题解决。
方法2:在样式style后添加scoped,使其中的css仅作用于当前组件中的元素,文档: Scoped CSS | Vue Loader (vuejs.org)。
参考:vue 路由跳转,导致页面样式错乱,刷新又好了的情况_韦金-CSDN博客 和 Vue Router路由跳转,导致页面样式错乱_花铛-CSDN博客_vue3路由跳转后排版错乱。
坑55(vue-router4、removeRoute()、router.options.routes未更新):在用户退出登录时,使用了removeRoute()来删除动态权限获取的菜单路由,但是router.options.routes未更新,依然保留动态路由在内。详细前情提要见 踩坑记15 动态路由 router.options.routes未更新 | vue升级 element-plus未适配vue3.2.x | vite glob导入动态加载组件,不能使用别名alias_Alloom的博客-CSDN博客,坑50(vue-router4、addRoute()、router.options.routes未更新),以下方法一、二与其对应。
相关API简要介绍:
removeRoute(),通过名称删除一条现有的路由。文档: API 参考 | Vue Router (vuejs.org)
router.options.routes,应该添加到路由的初始路由列表,文档: API 参考 | Vue Router (vuejs.org)
解决方案:
方法一(router.options.routes.splice(),router.options.routes.indexOf()):使用之前保存(vuex)的菜单信息生成的路由列表,在用removeRoute()删除路由记录的同时,使用router.options.routes.splice()和router.options.routes.indexOf()查找删除router.options.routes中动态添加的路由。
menuRoutes.map((r)=>{
router.removeRoute(r.name)
router.options.routes.splice(router.options.routes.indexOf(r),1)
})
方法二(vuex中的routes生成菜单):使用vuex,在store中存储路由列表,并用其生成菜单,避开router.options.routes。(认为可行,但并未实现)
附加:关于删除路由不可行的方案,参考 GitHub - PanJiaChen/vue-element-admin: A magical vue admin https://panjiachen.github.io/vue-element-admin ,在路由文件中定义导出了一个resetRouter的方法,其中使用更改router.matcher的方法重置路由。但实际尝试并不可行,推测可能与版本有关,参考源码用的是vue-router3.0.2,而此处目前使用的是最新的4.0.10。
关于router.matcher参考: 关于vue-router中路由权限用到的router.mtcher说明_一键写代码的博客-CSDN博客 和 vue-router工作原理概述和问题分析 - SegmentFault 思否。
by 莫得感情踩坑机(限定)
更多推荐
所有评论(0)