由于需求和安全性原因,将原来由前端根据用户权限去添加、剔除的路由逻辑改为由后端将不同权限的路由发送至前端进行路由拼接的写法(其实我也不清楚哪里不安全...没有进行注册的路由是无法访问的...如果访问的了只能说明剔除的逻辑写的有问题)但是客户是这么要求的,没办法....😭
一、核心代码(能实现效果,但可以优化)
router.beforeEach((to, from, next) => {
const userStore = useUserStore()
const usePermissionStore = useUserPermissionStore()
if (to.path !== '/login') {
if (userStore.getToken) {
const isExist = router.hasRoute(to.name!)
// 用于解决动态路由刷新白屏问题
if (!isExist) {
usePermissionStore.getDynamicRoutes.forEach(item => {
item.component = () => import(`@/layout/index.vue`)
if (item.children.length > 0) {
item.children.forEach((items: any) => {
items.component = () => import(`@/views/test/index.vue`) //这里的 test 是动态的,我是自己测才写死的
})
}
router.addRoute(item)
})
// 手动添加404路由匹配,解决初次刷新页面未找到动态路由直接进入404页面问题
constantRoutes.forEach((item) => {
router.addRoute(item)
})
next({ ...to, replace: true })
} else {
next()
}
} else {
next({ path: '/' })
}
} else {
if (userStore.getToken) {
next({ path: router.getRoutes()[0].path })
} else {
NProgress.start()
next()
NProgress.done()
}
}
})
主要逻辑都是在 全局前置守卫中
二、问题一(页面刷新、获取不到动态路由导致路由重定向)
两种情况
有404通配符
直接就重定向到404页面
无404通配符
白屏
原因:页面刷新后由于是异步获取的原因 在next() 函数放行之后才获取到
解决方法:
使用 next({ ...to, replace: true }) 来确保addRoute()
时动态添加的路由已经被完全加载上去。如果参数to不能找到对应的路由的话,就再执行一次beforeEach((to, from, next))
直到其中的next({ ...to})
能找到对应的路由为止。
切忌一定要正确的放行出口,否则就会形成死循环(当isExist为true的时候 执行 next()放行)
三、问题二(第一次执行beforeEach直接就重定向到404页面)
解决方法:404通配符也使用动态添加,在需要添加到路由后面动态添加404路由
// 手动添加404路由匹配,解决初次刷新页面未找到动态路由直接进入404页面问题
constantRoutes.forEach((item) => {
router.addRoute(item)
})
四、动态路由完成
至此动态路由的功能就完成了,还有一些是解决在 登录成功后访问 login 页面重定向的问题,在这里就不多提了....