vue3关于addRoute添加动态路由不切换页面、页面空白的问题
先说结论:vue3提供了addRoute(),同时也提供了removeRoute(),需要使用removeRoute()来清除动态路由再添加动态路由就能正常显示
做后台管理项目时遇到的一个问题,addRoute添加的动态路由可以切换路径,但是无法切换页面,只有刷新后才能正常切换。但是vue2就没有这个问题。
问题代码
permission.js
const whiteList = ['/login', '/404']
router.beforeEach(async (to, form, next) => {
nprogress.start()
if (useUserStore.token) {
if (to.path === '/login') {
next('/')
} else {
if (!useUserStore.userInfo.userId) {
const { roles } = await useUserStore.getUserInfo()
const routes = await useRoutesStore.setRoutes(roles.menus)
const newRoutes = [...routes, { path: "/:pathMatch(.*)", redirect: '/404', hidden: true }, { path: '/404', component: () => import('@/views/404.vue'), hidden: true }]
//-----------------------------------------------
//问题代码
for (const route of newRoutes) {
router.addRoute(route)
}
next({ ...to, replace: true })
//正常来讲,vue2这样写是没有问题的,添加动态路由后,
//重新跳转在重新进入路由守卫进入else的next()就可以正常跳转,但是vue3虽然也能跳转但就是不能正常显示页面
//-----------------------------------------------
} else {
next()
}
}
} else {
whiteList.includes(to.path) ? next() : next('/login')
}
nprogress.done()
})
logout.js
//此处是在登出的时候将动态路由清除,vue2写到此处动态权限已经是可以使用的了
logout() {
this.removeToken()
this.userInfo = {}
router.push('/login')
resetRouter()
useRoutes().setRoutes([])
}
解决方案一
juejin.cn/post/700336… 这是我找到一个作者分享的解决方案,我试了下可以解决,但是如果仅仅是在代码逻辑上来说感觉是不通的
const whiteList = ['/login', '/404']
++++++ let hasRoles = true //创建了一个状态位,来判断是否是第一次进入
router.beforeEach(async (to, form, next) => {
nprogress.start()
if (useUserStore.token) {
..........
//-----------------------------------------------
解决方案
+++++ if (hasRoles) {
// 如果是第一次进入则动态添加路由
for (const route of newRoutes) {
router.addRoute(route)
}
++++++ hasRoles = false //然后将状态位变为false 而逻辑不通则在这
next({ ...to, replace: true })
} else {
next()
}
//-----------------------------------------------
............
})
因为状态位变为false之后就不可能再变为true,除非刷新。如果用户登出,此时清空动态路由权限,在登陆时,按理说不会再添加动态路由权限,但奇怪的是,再次登录还是会有动态路由。
而且最大的bug在于。如果管理员登录后再退出,然后再使用一个权限很少的账号登录,虽然这个账号不会显示他没有的权限,但是如果他直接在浏览器地址栏内输入他没有权限的路径他也可以进去。除非刷新过。
解决方案二
方案一的使用其实可以看出,vue-router应该是对动态路由进行了缓存。而开头也提到了vue-router新提供的方法。 permission.js中的代码维持文章开始的原样,而在登出函数中调用removeRoute()方法即可 此方法应该是vue-router专门用来清除路由缓存的
logout() {
this.removeToken()
this.userInfo = {}
router.push('/login')
resetRouter()
useRoutes().setRoutes([])
for (const route of asyncRoutes) {
++++ router.removeRoute(route.name)
}
}
第一次写文章,哪里又不好的地方,希望大家可以提建议,一起进步
转载自:https://juejin.cn/post/7167001985727037470