版本环境
vue的版本是^2.6.12,将会使用到Vue.use()、Vue.directive()
适用环境
页面某些按钮,需要受到当前登录用户的“角色”“权限”的影响,通过store获取角色role和权限permission,通过自定义指令的方式,控制某一个组件的显示与隐藏。
文件架构
index.js文件,src/index.js
directive文件夹中三个文件,分别是src/directive/hasPermi.js、src/directive/hasRole.js、src/directive/index.js
前置配置
需要配合store使用,store.getter.roles角色,store.getters.permissions权限
文件内容
src/index.js文件
主要用于注册组件。用注册插件的方式,一次性注册两个指令
import Vue from 'vue'import permission from './directive'Vue.use(permission)// 省略其他
src/directive/index.js文件
import hasRole from './hasRole'
import hasPermi from './hasPermi'const install = function(Vue) {Vue.directive('hasRole', hasRole)Vue.directive('hasPermi', hasPermi)
}if (window.Vue) {window['hasRole'] = hasRolewindow['hasPermi'] = hasPermiVue.use(install); // eslint-disable-line
}export default install
vue2的官方文档对Vue.directive()做了解释,第一个参数为指令名称,文件中设置了两个指令,在组件中可以使用“v-hasPermi”和“v-hasRole”。就像使用v-if一样来控制组件。
第二个参数为一个function方法,入参为VUE对象。
控制的逻辑就是很简单的删除VNode下面的所有Element元素。在另外两个文件中可以具体看到。
src/directive/hasRole.js文件
/*** 角色权限处理*/import store from '@/store'export default {inserted(el, binding, vnode) {const { value } = bindingconst super_admin = "admin";const roles = store.getters && store.getters.rolesif (value && value instanceof Array && value.length > 0) {const roleFlag = valueconst hasRole = roles.some(role => {return super_admin === role || roleFlag.includes(role)})if (!hasRole) {el.parentNode && el.parentNode.removeChild(el)}} else {throw new Error(`请设置角色权限标签值"`)}}
}
inserted是钩子函数,在官方文档中有说明
在插入父节点的时候,判断是否有权限,如果没有的话,通过vnode删除下面的所有子节点。
考虑到可能被多个角色控制,因此v-hasRole要传入一个数组,通过判断是否具有指定的字符串,只要满足其中一个便显示。否则通过el对象拿到parentNode节点,通过父节点的removeChild移除自身。
src/directive/hasPermi.js文件
/*** 操作权限处理*/import store from '@/store'export default {inserted(el, binding, vnode) {const { value } = bindingconst all_permission = "*:*:*";const permissions = store.getters && store.getters.permissionsif (value && value instanceof Array && value.length > 0) {const permissionFlag = valueconst hasPermissions = permissions.some(permission => {return all_permission === permission || permissionFlag.includes(permission)})if (!hasPermissions) {el.parentNode && el.parentNode.removeChild(el)}} else {throw new Error(`请设置操作权限标签值`)}}
}
和角色控制一样的判断逻辑,不同的是,按钮这种权限,可以通过拼接或者特定字符指定。
假设一个list菜单,下面有两个页面add页面和edit页面,里面都有一个功能相同的按钮,但是想细致的区分两个权限。则,可以设置一个按钮的权限为“list:add:btn"另一个的按钮权限为"list:edit:btn”。对应的,如果同时有这两个的权限,可以将两个的值都设置为"list:all:btn"。
代码示例,v-hasRole也是一样
<el-button v-hasPermi="['list:add:btn']">确认</el-button><el-button v-hasPermi="['list:edit:btn']">确认</el-button>
精细到每一个组件的控制,还是按角色来粗略区分。要按实际业务需要,以及方便程度。