详细代码: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' // 为了隐藏
}
}
}
})