vue--角色管理

1,649 阅读1分钟

详细代码:github.com/PanJiaChen/… 需求: 根据用户的不同角色返回不同的前端页面(没有用vuex,分配权限后需退出登录。)

  • 难点:
  • 1.页面访问的限制 - 菜单栏访问: 是否全部显示菜单栏,全部则有“无权限页面”;地址栏访问:返回404页面
  • 2.页面中按钮等颗粒化控制
1.路由控制
    export const constantRouterMap = [ // 默认路由,无权限控制
        {
             path: '/',
            name: 'index',
            component: index
        }
    ]
    export const asyncRouterMap = [
        {
            path: 'project',
            component: () => import('@/pages/myqingju2.0/projectManage'),
            meta: {
              roles: ['eDJl'] // 后台返回权限指字段绑定
            }
        }
    ]
    export default new Router({
      mode: 'history',
      routes: constantRouterMap,
     })
2. 筛选符合权限的路由
/**
 * 通过meta.role判断是否与当前用户权限匹配
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    // console.log(route.meta.roles, ' route.meta.roles')
    return roles.some(role => route.meta.roles.indexOf(role) >= 0)
  } else {
    return true
  }
}
/**
 * 递归过滤异步路由表,返回符合用户角色权限的路由表
 * @param asyncRouterMap
 * @param roles
 */
function filterAsyncRouter(map, roles) {
  const accessedRouters = map.filter(route => {
    if (hasPermission(roles, route)) {
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children, roles)
      }
      // 子导航的子导航
      if (route.meta && route.meta.children && route.meta.children.length) {
        route.meta.children = filterAsyncRouter(route.meta.children, roles)
      }
      return true
    }
    return false
  })
  return accessedRouters
}
3.路由导航钩子
    import router from './router'
    import { asyncRouterMap, constantRouterMap } from '@/router'
    let bool = true
    router.beforeEach((to, from, next) => {
      let firmCurrentUserInfo = localStorage.firmCurrentUserInfo && JSON.parse(localStorage.firmCurrentUserInfo)
      console.log(firmCurrentUserInfo, 'firmCurrentUserInfo')
      if ( bool && firmCurrentUserInfo ) {
        bool = false // 不加会一直循环
        let accessedRouters = []
        let map = deepCopy(asyncRouterMap)
        let firstroles = firmCurrentUserInfo.baseFirstFunctionList.map(item => item.functionEnum)
        let secondroles = firmCurrentUserInfo.baseSecondFunctionList.map(item => item.functionEnum)
        // let thirdroles = firmCurrentUserInfo.baseFunctionList.map(item => item.functionEnum)
        let ROLES = []
        ROLES = ROLES.concat(firstroles, secondroles)
        localStorage.setItem('ROLES-qingju', JSON.stringify(ROLES)) // 存储到内存中
        accessedRouters = filterAsyncRouter(map, ROLES)
        // 动态添加路由
        let allRouters = constantRouterMap.concat(accessedRouters)
        console.log(allRouters, 'allRouters')
        router.addRoutes(allRouters) // !!!
        next({ ...to }) // ?
      }
      next()
    })
4.页面中按钮或操作 -- 自定义命令
/* 颗粒权限 */
Vue.directive('has', {
  inserted(el, binding) {
    let list = JSON.parse(localStorage.firmCurrentUserInfo).baseFunctionList
    if (list) {
      let hasPermission = list.some((role, index) => {
        if (role) {
          return binding.value.includes(role.functionEnum)
        }
      })
      if (!hasPermission) { // 为什么父元素为null
        el.parentNode && el.parentNode.removeChild(el)
        el.style.display = 'none' // 为了隐藏
      }
    }
  }
})