版本環境
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>
精細到每一個組件的控制,還是按角色來粗略區分。要按實際業務需要,以及方便程度。