在开发Vue后台管理平台的项目中,在配合用户权限管理时,使用router.addRoutes()设置动态路由后,页面刷新后重定向到404。
解决方案:添加动态路由之后,重新进入该动态路由地址。
由于addRoutes是一个异步操作,在没有重新进入该动态路由地址时,router.beforeEach会直接放行。然而next(to.path)存在轮询机制,它会直到Router.addRoutes()该异步操作完成之后,再进入该动态路由地址。
router.beforeEach(async(to, from, next) => {
// 开启进度条
NProgress.start()
// 判断是否有token
const token = store.getters.token
if (token) {
// 判断是否去登录页
if (to.path === '/login') {
next('/')
// 关闭进度条
NProgress.done()
} else {
/**、8.、
去到所有页面之前都会走这里
先判断有没有用户信息
有,直接放行
没有,先获取到用户信息再放行
*/
// 获取用户信息
if (!store.getters.userId) {
// 获取用户的权限点
const { roles } = await store.dispatch('user/getUserInfo')
// 从动态路由数组中筛选出动态路由
const filterRoutes = asyncRoutes.filter(item => {
return roles.menus.includes(item.name)
})
store.commit('user/setRoutes', filterRoutes)
/**
问题1:addRoutes方法存在已知缺陷,官方给的解决方案是:重新再进一次 next(to.path)
问题2:{ path: '*', redirect: '/404', hidden: true } 必须放在路由规则数组的最后
*/
router.addRoutes([...filterRoutes, { path: '*', redirect: '/404', hidden: true }])
next(to.path)
} else {
next()
}
}
} else {
// 判断是否在白名单
if (whiteList.includes(to.path)) {
next()
} else {
next('/login')
// 关闭进度条
NProgress.done()
}
}
})