看需求,比较简单的就是那种没有权限直接跳转到没有权限的页面,另外一种就是控制显示隐藏,没有权限就不显示这个菜单
我这边是根据我们后台的设定处理的,我们这边给一个权限码数组.
authCodeList:["SYS:DEPARTMENT","WORKSHEET","WORKSHEET:TEMPLATE","WORKSHEET:TEMPLATE:LIST","WORKSHEET:TEMPLATE:IMPORT","WORKSHEET_LIST","WORKSHEET:DETAIL","WORKSHEET:APPROVAL","WORKSHEET:ADD","HOMEPAGE","SYS","SYS:ROLE","SYS:ROLE:MODOFY","SYS:ROLE:ADD","SYS:ROLE:DELETE","SYS:USER","SYS:USER:CREATE","SYS:USER:QUERY","SYS:USER:MODIFY"]这种我看来不是很好的,因为一眼看去没什么层次.我觉得更好的设计是层次感要更鲜明一些,用多位数组可能更好
但是这样的结构处理起来更简单一点,不用搞什么迭代
,主要是看meta这个里面的字段的设置,如果没有配置permission,默认是按照不需要权限做处理
配置了之后,就要去对比是不是在权限列表里面,如果有的话就生成一个动态路由表.根据动态路由表里面的设置去做相应的跳转
路由设置就比较简单了.我这边就用权限管理页面做举例
export const asyncRouterMap = [
{
path: '/',
name: 'index',
component: BasicLayout,
meta: { title: '首页', },
redirect: '/dashboard/workplace',
children: [
// dashboard
{
path: '/dashboard',
name: 'dashboard',
redirect: '/dashboard/workplace',
component: RouteView,
meta: { title: '首页', keepAlive: true, icon: 'home' },
children: [
{
path: '/dashboard/workplace',
name: 'Workplace',
component: () => import('@/views/dashboard/Workplace'),
meta: { title: '首页', keepAlive: true, hiddenHeaderContent: true }
}
]
},
// setting
{
path: '/settings',
name: 'settingsPage',
component: PageView,
redirect: '/settings/Department',
meta: { title: '权限管理', icon: 'safety' },
children: [
{
path: '/settings/Department/tree-list',
name: 'MenuManage',
component: () => import('@/views/settings/MenuManage'),
// meta: { title: '菜单管理', keepAlive: true, permission:['MENUMANAGE']}
meta: { title: '菜单管理', keepAlive: true }
},
{
path: '/settings/Department',
name: 'SettingsDepartment',
component: () => import('@/views/settings/Department'),
meta: { title: '部门管理', keepAlive: false, permission: ['SYS:DEPARTMENT'] }
},
{
path: '/settings/Role',
name: 'Role',
component: () => import('@/views/settings/Role'),
meta: { title: '角色管理', keepAlive: false }
// meta: { title: '角色管理', keepAlive: false, permission: ['SYS:ROLE'] }
},
{
path: '/settings/UserManage',
name: 'UserManage',
component: () => import('@/views/settings/UserManage'),
meta: { title: '用户管理', keepAlive: false, permission: ['SYS:USER'] }
}
]
}
]
},
{
path: '*', redirect: '/404', hidden: true
}
]
做这个功能,基本都是从路由跳转那里下手,我现在实现的是最简单的.
function includePermission (permissions = []) {
// 这里要判断的权限没有设置的话,就等于不需要权限,直接返回 true
if (!permissions.length) return true
const permissionList = store.state.user.userInfo.authCodeList
return !!permissions.find(permission => permissionList.includes(permission))
}
router.beforeEach((to, from, next) => {
if (Vue.ls.get(ACCESS_TOKEN)) {
/* has token */
if (to.path === '/user/login') {
next({ path: defaultRoutePath })
NProgress.done()
} else {
const { permission } = to.meta
const roles = store.state.user.userInfo.authCodeList
store.dispatch('GenerateRoutes', { roles }).then(() => {
//把生成的动态路由表添加进来,这个不是总路由表,GenerateRoutes代码
router.addRoutes(store.getters.addRouters)// 这里动态生成路由
})
if (permission) {
//这段其实不会走进来,因为没有权限的都不会生成这个路由信息,参考
const hasPermission = includePermission(permission)
if (!hasPermission) next({ path: '/403' })
}
next()
}
} else {
if (whiteList.includes(to.name)) {
// 在免登录白名单,直接进入
next()
} else {
next({ path: '/user/login', query: { redirect: to.fullPath } })
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
router.addRoutes(routes: Array) 路由对象是不可变 (immutable) 的,每次成功的导航后都会产生一个新的对象。动态添加更多的路由规则。参数必须是一个符合 routes 选项要求的数组。
动态生成路由的代码
actions: {
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
const accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
//这个routermap就是上面的总的路由表.这个是个迭代.因为路由里面可能有多层子路由
function filterAsyncRouter (routerMap, roles) {
//filter函数可以看成是一个过滤函数,返回符合条件的元素的数组返回false则移除,true则加进来
const accessedRouters = routerMap.filter(route => {
if (hasPermission(roles, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, roles)
}
return true //有权限.则添加进来
}
return false
})
return accessedRouters
}
/**
* 过滤账户是否拥有某一个权限,并将菜单从加载列表移除
*
* @param permission
* @param route
* @returns {boolean}
*/
function hasPermission (permission, route) {
if (route.meta && route.meta.permission) {
let flag = false
for (let i = 0, len = permission.length; i flag = route.meta.permission.includes(permission[i])
if (flag) {
return true
}
}
return false
}
return true
}
这里基本就完成了一个动态路由表的设计.重点也是这块.再往下细分的话,就要涉及到按钮等其他控件的显示隐藏的控制了.我们现在还是根据上面的继续做
这里是通过自定义指令的方式来处理.比如这里又一个a标签
v-action:WORKSHEET:ALLLIST
> 所有工单
我们现在要实现的就是 v-action:WORKSHEET:ALLLIST怎样通过这个标签来控制控件的显示隐藏
import Vue from 'vue'
import store from '@/store'
/**
* Action 权限指令
* 指令用法:
*
* - 当前用户没有权限时,组件上使用了该指令则会被隐藏
* - 当后台权限跟 pro 提供的模式不同时,只需要针对这里的权限过滤进行修改即可
*
* @see https://github.com/sendya/ant-design-pro-vue/pull/53
*/
const action = Vue.directive('action', {
inserted: function (el, binding, vnode) {
const actionName = binding.arg
const roles = store.getters.roles
const elVal = vnode.context.$route.meta.permission
// console.log('action----',elVal,actionName,roles)
const permissionId = elVal instanceof String && [elVal] || elVal
var isContainsPermission = actionName && roles.includes(actionName)
if (!isContainsPermission) {
el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none')
}
/* roles.forEach(p => {
if (!permissionId.includes(p.permissionId)) {
return
}
if (p && !p.includes(actionName)) {
el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none')
}
})*/
}
})
export default action
---------------------------
等有时间再补充完整.,今天先写到这里.
本文来自投稿,不代表本人立场,如若转载,请注明出处:http://www.sosokankan.com/article/1805901.html