Router.addRoutes() 设置动态路由,页面刷新后无效

1,949 阅读1分钟

在开发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()
    }
  }
})