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)}//不需要权限的白名单pathconst 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 acce***outes = await store.dispatch('permission/generateRoutes', roles)
      //通过addRoutes加载路由  router.addRoutes(acce***outes)
      //存储已加载的状态,下次就不会进入这个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 + Element UI 实现权限管理系统 前端篇(七):功能组件封装