在Vue的權(quán)限功能開發(fā)過程中通常有頁面級(jí)別和按鈕級(jí)別的權(quán)限控制,頁面級(jí)別的權(quán)限相對(duì)好處理一下埃元,一般情況是后端根據(jù)登錄的用戶賬號(hào)只下發(fā)用戶有權(quán)限的頁面菜單,前端動(dòng)態(tài)渲染頁面跳轉(zhuǎn)的菜單即可媚狰。
相比較而言更細(xì)顆粒度的按鈕級(jí)別的權(quán)限控制相對(duì)麻煩點(diǎn)岛杀,這里我想講兩種Vue按鈕基本控制的級(jí)別思路。
方法一:封裝權(quán)限指令控制按鈕
第一步:
登錄的時(shí)候讓后端返回當(dāng)前賬號(hào)的角色崭孤,即 role类嗤,存入Vue中;
第二步:
封裝vue自定義指令裳瘪,來判斷用戶權(quán)限土浸,具體思路是 從Vuex取出登錄后后端角色信息和指令中用戶傳入的角色信息進(jìn)步比對(duì)罪针,如果存在即有權(quán)限彭羹,如果不存在則無權(quán)限。
src/directive/permission/permission.js
import store from '@/store'
function checkPermission(el, binding) {
const { value } = binding
const roles = store.getters && store.getters.roles
// 判斷角色信息是否存在并且是數(shù)組
if (value && value instanceof Array) {
// 當(dāng)角色存在時(shí)
if (value.length > 0) {
const permissionRoles = value
/**
* 判斷vuex中獲取的角色信息是否符合
* some() 方法用于檢測(cè)數(shù)組中的元素是否滿足指定條件(函數(shù)提供)泪酱。
* some() 方法會(huì)依次執(zhí)行數(shù)組的每個(gè)元素:
* 如果有一個(gè)元素滿足條件派殷,則表達(dá)式返回true , 剩余的元素不會(huì)再執(zhí)行檢測(cè)。
* 如果沒有滿足條件的元素墓阀,則返回false毡惜。
* 注意: some() 不會(huì)對(duì)空數(shù)組進(jìn)行檢測(cè)。
* 注意: some() 不會(huì)改變?cè)紨?shù)組斯撮。
*/
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
/**
* 如果不符合則取出這個(gè)dom
*/
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
}
export default {
inserted(el, binding) {
checkPermission(el, binding)
},
update(el, binding) {
checkPermission(el, binding)
}
}
src/directive/permission/index.js
import permission from './permission'
const install = function(Vue) {
Vue.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install); // eslint-disable-line
}
permission.install = install
export default permission
mian.js中全局注冊(cè)
import permission from './directive/permission'
Vue.use(permission)
vue頁面v-permission指令的使用
<div :key="key" style="margin-top:30px;">
<div>
<!-- 只有 admin 角色可以看見 -->
<span v-permission="['admin']" class="permission-alert">
Only
<el-tag class="permission-tag" size="small">admin</el-tag> can see this
</span>
<el-tag v-permission="['admin']" class="permission-sourceCode" type="info">
v-permission="['admin']"
</el-tag>
</div>
<div>
<!-- 只有 editor 用戶可以看見 -->
<span v-permission="['editor']" class="permission-alert">
Only
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
</span>
<el-tag v-permission="['editor']" class="permission-sourceCode" type="info">
v-permission="['editor']"
</el-tag>
</div>
<div>
<!-- admin 和 editor兩個(gè)角色都可以看見 -->
<span v-permission="['admin','editor']" class="permission-alert">
Both
<el-tag class="permission-tag" size="small">admin</el-tag> and
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
</span>
<el-tag v-permission="['admin','editor']" class="permission-sourceCode" type="info">
v-permission="['admin','editor']"
</el-tag>
</div>
</div>
方法二:使用全局權(quán)限判斷函數(shù)
封裝權(quán)限判斷函數(shù) src/utils/permission.js
import store from '@/store'
/**
* @param {Array} value
* @returns {Boolean}
* @example see @/views/permission/directive.vue
*/
export default function checkPermission(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
return hasPermission
} else {
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}
}
在mian.js中引入
import { checkPermission } from "@/api/system/dict/data";
// 全局方法掛載
Vue.prototype.checkPermission = checkPermission
在頁面中使用
<div :key="'checkPermission'+key" style="margin-top:60px;">
<!-- 只有角色為 admin 時(shí)顯示 -->
<el-tabs type="border-card" style="width:550px;">
<el-tab-pane v-if="checkPermission(['admin'])" label="Admin">
Admin can see this
<el-tag class="permission-sourceCode" type="info">
v-if="checkPermission(['admin'])"
</el-tag>
</el-tab-pane>
<!-- 只有角色為 editor 時(shí)顯示 -->
<el-tab-pane v-if="checkPermission(['editor'])" label="Editor">
Editor can see this
<el-tag class="permission-sourceCode" type="info">
v-if="checkPermission(['editor'])"
</el-tag>
</el-tab-pane>
<!-- 當(dāng)角色為 admin 或 editor 時(shí)顯示 -->
<el-tab-pane v-if="checkPermission(['admin','editor'])" label="Admin-OR-Editor">
Both admin or editor can see this
<el-tag class="permission-sourceCode" type="info">
v-if="checkPermission(['admin','editor'])"
</el-tag>
</el-tab-pane>
</el-tabs>
</div>
【警告】在某些情況下经伙,使用v-permission將無效。例如:元素UI的選項(xiàng)卡組件或el表格列以及其他動(dòng)態(tài)渲染dom的場(chǎng)景勿锅。您只能使用v-if來執(zhí)行此操作帕膜。
參考文獻(xiàn):
參考文獻(xiàn)二溢十;
參考文獻(xiàn)三垮刹;