vue-router+vuex的坑

2022-11-10 14:23:12 浏览数 (1)

问题描述

最近使用vue-h5-template写一个移动端demo,想配合后端搞一个动态路由,于是想起以前使用过的vue-element-admin项目里的动态路由方案,大概思路就是准备两个路由数组,一个是不需要经过角色过滤的constantRoutes,一个是需要根据角色过滤的asyncRoutes,在用户登录的时候根据用户角色来过滤asyncRoutes,并将路由信息存放到vuex中

代码语言:javascript复制
// 不需要经过用户角色过滤的路由,也就是任何人都可以看到的
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true,
    name: 'Login',
    meta: {
      title: '登录'
    }
  },
  {
    path: '/register',
    component: () => import('@/views/register/index'),
    hidden: true,
    name: 'Register',
    meta: {
      title: '注册'
    }
  },
  {
    path: '/',
    component: () => import('@/views/layouts/index'),
    redirect: '/my',
    meta: {
      title: '首页',
      keepAlive: false
    },
    children: []
  },
  {
    path: '/404',
    name: '404',
    component: () => import('@/views/404/index'),
    hidden: true
  }
]
// 需要根据用户角色过滤的路由
export const asyncRoutes = [
  ...userRouter,
  // 这个一定要放到最后,匹配不到路由的时候会走该路由,我这里是匹配不到路由就回my页面
  {path: '*', redirect: '/my', hidden: true}
]

坑一

路由配置缺少了{path: '*', redirect: '/my', hidden: true}{path: '*', redirect: '/my', hidden: true}没在路由数组的最后一个。 path:'*'表示匹配任何路由,一般来重定向到404页面,将该配置放到路由数组最后,来达到没有匹配到前边/login、/register和asyncRoutes等路由时,走path:'*'路由,我这里没有重定向至404,而是重定向到my页面

坑二

vuex的数据在刷新页面时会丢失,导致在页面刷新后,存储于vuex中的router丢失,从而导致部分路由找不到

解决

因为roles也是在vuex中存储,在路由守卫中来判断roles是否为空,如果为空,则重新请求后端获取roles构建路由

代码语言:javascript复制
router.beforeEach(async (to, from, next) => {
  // start progress bar
  // NProgress.start()

  // set page title
  document.title = defaultSettings.title

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({path: '/'})
      // NProgress.done()
    } else {
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          // 构建动态路由 
          // get user info
          const {roles} = await store.dispatch('user/getInfo')
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          // dynamically add accessible routes
          for (const accessRoute of accessRoutes) {
            router.addRoute(accessRoute)
          }
          next({...to, replace: true})
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          // Message.error(error || 'Has Error')
          Toast.fail(error || 'Has Error')
          // next(`/login?redirect=${to.path}`)
          next(`/login?redirect=${to.path}`)
          // NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      // next(`/login?redirect=${to.path}`)
      next(`/login?redirect=${to.path}`)
      // NProgress.done()
    }
  }
})

0 人点赞