vue-router 实现动态路由加载,权限管理

import Vue from 'vue'
import Router from 'vue-router'
import store from '@/store/index'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import gatewayHomeRouter from './gatewayHome'
Vue.use(Router)
//不需要权限的路由
export const constantRoutes = [
  {
    path: '/',
    redirect: '/entrance'
  },
  {
    path: '/entrance',
    component: () => import('@/views/Index.vue'),
    meta: { isEntrance: true }
  },
  {
    path: '/register',
    name: 'register',
    component: () => import('@/views/common/Register.vue')
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/views/common/Login.vue')
  },
  {
    path: '/logout',
    name: 'logout',
    component: () => import('@/views/common/Logout.vue')
  },
  {
    path: '/quit',
    name: 'quit',
    component: () => import('@/views/common/Quit.vue')
  },
  {
    path: '/error/:id',
    name: '404',
    component: () => import('@/views/common/404.vue')
  },
  {
    path: '/Admittance',
    name: 'Admittance',
    component: () => import('@/views/common/Admittance.vue')
  },
  // gatewayHomeRouter
]
export const asyncRoutes = gatewayHomeRouter
const createRouter = () => new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: constantRoutes
})

const router: any = createRouter()
//写一个重置路由的方法,切换用户后,或者退出时清除动态加载的路由
export function resetRouter() {
  const newRouter: any = createRouter()
  router.matcher = newRouter.matcher // 新路由实例matcer,赋值给旧路由实例的matcher,(相当于replaceRouter)
}
//不需要权限的白名单path
const whiteList = ['/entrance', '/register', '/login', '/logout', '/error', '/Admittance', '/quit']
router.beforeEach(async (to, from, next) => {
  NProgress.start()
 //登录后的用户有token
  const hasToken = sessionStorage.getItem('Authorization')
  //注销后的用户的识别
  let isEffect = store.state.isEffect
  if (isEffect === '0') {
    if (to.path !== '/quit') {
      next('/quit')
    }
  }
  if (hasToken) {

    if (to.path === '/login') {
      // 已登录的用户,想去登录页就重定向到首页
      next({ path: '/' })
      NProgress.done()
    } else {
      if (store.state.isMountedRoutes) {
        if (to.path === '/entrance') {
          next('/home')
        }
        next()
      } else {
        try {
      //登录后获取用户角色
          const { roleTypeDetail } = await store.dispatch('COMMIT_USER_LOGIN')
          let roles: any = [Number(roleTypeDetail)]
      //根据角色遍历出来对应可以显示的路由
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
      //通过addRoutes加载路由
          router.addRoutes(accessRoutes)
      //存储已加载的状态,下次就不会进入这个try
          store.commit('SET_IS_MOUNTED_ROUTES', true)
          NProgress.done()
          next({ path: to.path })
        } catch (error) {
          // 清除token重新跳转登录页
          // await store.dispatch('user/resetToken')
          store.dispatch('COMMIT_LOGOUT')
          next(`/login`)
          NProgress.done()
        }
      }
    }
  } else {
    //白名单直接里边请
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      // 其他无权限的重定向到登录页
      next(`/login`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

export default router

下面是permission.ts文件,这个文件只做了一件事,就是根据路由meta对象的某个属性值,来过滤出来对应值拥有的路由对象,以供addRoutes,直接拿过去用、

import { asyncRoutes, constantRoutes } from '@/router'
//判断是否有权限
function hasPermission(roles, route) {
    if (route.meta && route.meta.identity) {
        return roles.some(role => route.meta.identity.includes(role))
    } else {
        return true
    }
}
//过滤出有权限的路由
export function filterAsyncRoutes(routes, roles) {
    const res: any = []
    routes.forEach(route => {
        const tmp = { ...route }
        if (hasPermission(roles, tmp)) {
            if (tmp.children) {
                tmp.children = filterAsyncRoutes(tmp.children, roles)
            }
            res.push(tmp)
        }
    })
    return res
}
const permission = {
    namespaced: true,
    state: {
        routes: [],
        addRoutes: []
    },
    mutations: {
        SET_ROUTES: (state, routes) => {
            state.addRoutes = routes       //把之前的路由和后过滤出来的路由拼接起来一个新数组
            state.routes = constantRoutes.concat(routes)
        }
    },
    actions: {     //构建路由的函数
        async generateRoutes({ commit }, roles) {
            return new Promise(resolve => {
                let accessedRoutes
                if (roles.includes(5)) {
                    accessedRoutes = asyncRoutes || []
                } else {
                    accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
                }
                commit('SET_ROUTES', accessedRoutes)
                resolve(accessedRoutes)
            })
        }
    },
    getters: {},
}//导出供使用
export default permission

下面是那个倒霉的要被过滤来过滤去的路由数组

const gatewayHomeRouter = [{
  path: '/home',
  component: () => import('@/views/home/Index.vue'),
  children: [
    {
      path: '',
      redirect: 'gateway'
    },
    {
      path: 'gateway',
      name: 'gateway',
      meta: {
        title: '首页',
        icon: 'el-icon-rank',
        identity: [1, 2, 3, 4, 5]//这就是几种角色
      },
      component: () => import('@/views/home/gateway/Index.vue')
    },
    {
      path: 'supplierMaintenance',
      name: 'supplierMaintenance',
      meta: {
        title: '供应商基本信息维护',
        icon: 'el-icon-rank',
        identity: [2, 3, 4, 5]
      },
      component: () => import('@/views/home/supplierMaintenance/Index.vue')
    },
    {
      path: 'personnelManagement',
      name: 'personnelManagement',
      meta: {
        title: '供应商人员管理',
        icon: 'el-icon-rank',
        identity: [5]
      },
      component: () => import('@/views/home/personnelManagement/Index.vue')
    },
    {
      path: 'userInfo',
      name: 'userInfo',
      meta: {
        title: '个人信息',
        icon: 'el-icon-rank',
        identity: [2, 3, 4, 5]
 
      },
      component: () => import('@/views/home/userInfo/Index.vue')
    },
  ]
}]
export default gatewayHomeRouter

原创:vue-router 实现动态路由加载,权限管理 - 现象886 - 博客园

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值