vue权限路由实现的方法示例总结(2)

  • 菜单跟路由耦合在一起,定义路由的时候还有添加菜单显示标题,图标之类的信息,而且路由不一定作为菜单显示,还要多加字段进行标识
  • 使用addRoutes动态挂载路由

    addRoutes允许在应用初始化之后,动态的挂载路由。有了这个新姿势,就不用像前一种方式那样要在应用初始化之要对路由进行筛选。

    实现

    应用初始化的时候先挂载不需要权限控制的路由,比如登录页,404等错误页。

    有个问题,addRoutes应该何时调用,在哪里调用

    登录后,获取用户的权限信息,然后筛选有权限访问的路由,再调用addRoutes添加路由。这个方法是可行的。但是不可能每次进入应用都需要登录,用户刷新浏览器又要登陆一次。

    所以addRoutes还是要在全局路由守卫里进行调用

    import router from './router'
    import store from './store'
    import { Message } from 'element-ui'
    import NProgress from 'nprogress' // progress bar
    import 'nprogress/nprogress.css'// progress bar style
    import { getToken } from '@/utils/auth' // getToken from cookie
    
    NProgress.configure({ showSpinner: false })// NProgress Configuration
    
    // permission judge function
    function hasPermission(roles, permissionRoles) {
     if (roles.indexOf('admin') >= 0) return true // admin permission passed directly
     if (!permissionRoles) return true
     return roles.some(role => permissionRoles.indexOf(role) >= 0)
    }
    
    const whiteList = ['/login', '/authredirect']// no redirect whitelist
    
    router.beforeEach((to, from, next) => {
     NProgress.start() // start progress bar
     if (getToken()) { // determine if there has token
     /* has token*/
     if (to.path === '/login') {
     next({ path: '/' })
     NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
     } else {
     if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
     store.dispatch('GetUserInfo').then(res => { // 拉取user_info
      const roles = res.data.roles // note: roles must be a array! such as: ['editor','develop']
      store.dispatch('GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表
      router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
      next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
      })
     }).catch((err) => {
      store.dispatch('FedLogOut').then(() => {
      Message.error(err || 'Verification failed, please login again')
      next({ path: '/' })
      })
     })
     } else {
     // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
     if (hasPermission(store.getters.roles, to.meta.roles)) {
      next()//
     } else {
      next({ path: '/401', replace: true, query: { noGoBack: true }})
     }
     // 可删 ↑
     }
     }
     } else {
     /* has no token*/
     if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
     next()
     } else {
     next('/login') // 否则全部重定向到登录页
     NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
     }
     }
    })
    
    router.afterEach(() => {
     NProgress.done() // finish progress bar
    })
          

    内容版权声明:除非注明,否则皆为本站原创文章。

    转载注明出处:https://www.heiqu.com/37.html