在很多后台管理系统中,常常需要做按钮权限控制。
前端需要根据后端传来的菜单数据控制是否显示某个按钮功能。
新建 permissions.js 文件
//导入vue实例
import Vue from 'vue';
获取储存在vuex中的菜单数据
// 获取当前用户菜单
[types.SET_USER_MENUS] : async({
commit,
dispatch
}) = >{
let {
body
} = await userMenusGet() if (body && JSON.stringify(body) !== '{}') {
permissions.checkKey(body.menuList)
}
return body ? body: null
},
//permissions.js 文件
import Vue from 'vue'
let menuList = []
const checkKey = list => {
// console.log(list, '获取Vuex里的菜单列表')
menuList = list
return list
}
export default {
checkKey
}
遍历菜单数据对比是否有权限
遍历对比name字段是否与传入自定义参数name值相等,匹配成功则表明有权限,则不需要隐藏,返回false,失败没有权限,则返回true,需要隐藏
// 检测传入的元素key是否可以显示
const checkArray = (menuList, name = '', newArr) => {
newArr = newArr || []
// 获取权限数组
// console.log(menuList, '获取权限数组')
let state = false
for (let i = 0; menuList && i < menuList.length; i++) {
const item = menuList[i]
if (item.nameEn) {
newArr.push(item.nameEn)
if (item.hasChildren && item.children.length > 0) {
checkArray(item.children, name, newArr)
}
}
}
/* console.log(newArr, 'newArrnewArrnewArrnewArr')
console.log(newArr.includes(name), '检测++++++++++++++++++++++') */
newArr.includes(name) ? (state = false) : (state = true)
return state
}
设置vue自定义指令,注册一个全局自定义指令
/**
* 使用Vue.directive声明自定义指令v-has
* inserted:被绑定元素插入父节点时调用
* el:指令所绑定的元素,可以用来直接操作 DOM
* binding.value:指令的绑定值,例如:v-has="Home" 中,绑定值为 Home。
* 使用示例 <el-button v-has="'Home'">权限按钮1</el-button>
*/
Vue.directive('has', {
inserted: function(el, binding) {
let permission = binding.value // 获取到 v-has的值
// console.log(permission, 'permission+++++++++++++++++++++++')
// 代表某个元素需要通过权限验证
if (permission) {
let hasPermission = checkArray(menuList, permission)
// console.log(menuList, hasPermission, 'hasPermission++++++++++++')
if (hasPermission) {
// 没有权限 移除Dom元素
el.parentNode && el.parentNode.removeChild(el)
}
}
}
})
如果不是按钮,而是要隐藏某个页签可以使用自定义属性,通过v-if判断
/**
* 如果不是按钮,而是要隐藏某个页签可以使用自定义属性,通过v-if判断
* 使用示例 <el-tab-pane label="配置" v-if="$has('Home')"></el-tab-pane>
*/
Vue.prototype.$has = val => {
// console.log(val, 'val++++++++++++++++++++++++++++++')
//最终的结果需要是boolean类型
return checkArray(menuList, val)
}
使用方式,全局挂载
在 main.js 文件中引入
import permissions from '@/libs/permissions'
使用方式(按钮权限控制隐藏)
<el-button type="primary" v-has="'noVal'">这个按钮不显示</el-button>
使用方式(隐藏某个标签)
<p v-text="这个标签不显示" v-if="$has('noVal')"></p>
最终代码与效果
//创建自定义指令并删除不显示的按钮
import Vue from 'vue'
let menuList = []
const checkKey = list => {
// console.log(list, '获取Vuex里的菜单列表')
menuList = list
return list
}
// 检测传入的元素key是否可以显示
const checkArray = (menuList, name = '', newArr) => {
newArr = newArr || []
// 获取权限数组
// console.log(menuList, '获取权限数组')
let state = false
for (let i = 0; menuList && i < menuList.length; i++) {
const item = menuList[i]
if (item.nameEn) {
newArr.push(item.nameEn)
if (item.hasChildren && item.children.length > 0) {
checkArray(item.children, name, newArr)
}
}
}
/* console.log(newArr, 'newArrnewArrnewArrnewArr')
console.log(newArr.includes(name), '检测++++++++++++++++++++++') */
newArr.includes(name) ? (state = false) : (state = true)
return state
}
/**
* 使用Vue.directive声明自定义指令v-has
* inserted:被绑定元素插入父节点时调用
* el:指令所绑定的元素,可以用来直接操作 DOM
* binding.value:指令的绑定值,例如:v-has="Home" 中,绑定值为 Home。
* 使用示例 <el-button v-has="'Home'">权限按钮1</el-button>
*/
Vue.directive('has', {
inserted: function(el, binding) {
let permission = binding.value // 获取到 v-has的值
// console.log(permission, 'permission+++++++++++++++++++++++')
// 代表某个元素需要通过权限验证
if (permission) {
let hasPermission = checkArray(menuList, permission)
// console.log(menuList, hasPermission, 'hasPermission++++++++++++')
if (hasPermission) {
// 没有权限 移除Dom元素
el.parentNode && el.parentNode.removeChild(el)
}
}
}
})
/**
* 如果不是按钮,而是要隐藏某个页签可以使用自定义属性,通过v-if判断
* 使用示例 <el-tab-pane label="配置" v-if="$has('Home')"></el-tab-pane>
*/
Vue.prototype.$has = val => {
// console.log(val, 'val++++++++++++++++++++++++++++++')
//最终的结果需要是boolean类型
return checkArray(menuList, val)
}
export default {
checkKey
}