按钮级的权限控制
1.背景
近期在开发云服务项目,对于button级别的权限控制有一定的要求,但是一处处改的话比较吃力不讨好,费时费力,就想着做一个封装。
基础环境:vue + element
2.尝试
1⃣️封装button组件
第一想法就是封装一个button组件,然后在需要的地方引用,但是这个想法还是有个bug,不管button组件封装的如何,但是总需要把之前的button全部替换为新的button组件,这个虽然省一点时间,但是很不满意。当然,代码还是要贴出来,留个纪念吧。
<template>
<el-button
:loading="buttonDct.loading"
:disabled="disabledStatus"
:type="buttonDct.type"
:icon="buttonDct.icon"
:plain="buttonStyle.plain"
:round="buttonStyle.round"
:circle="buttonStyle.circle"
@click="clickBtn"
>
<slot/>
</el-button>
</template>
<script>
import {currentActionIsDisabled} from "@/helpers/policy.js";
export default {
props: {
/**
* button属性
* type 类型 string primary / success / warning / danger / info / text, 默认为空
* icon 图标类名 string, 默认为空
* action 事件名 string, 默认为空
* product 产品名 string, 默认为空
* loading 是否加载中状态 boolean,默认false
* buttonStyle 按钮风格 plain(朴素按钮)/round(圆角按钮)/circle(圆形按钮), 默认为空
*/
buttonDct: {
type: Object,
default: () => {
return {
type: "",
icon: "",
action: "",
product: "",
loading: false,
buttonStyle: "",
};
},
},
},
data() {
return {
// 是否禁用,默认是
disabledStatus: true,
// 按钮风格字典
buttonStyle: {
"plain": false,
"round": false,
"circle": false,
},
};
},
watch: {
buttonDct: {
handler: function() {
this.loadDisabledStatus();
},
immediate: true,
deep: true,
},
},
methods: {
// 按钮的点击事件
clickBtn() {
this.$emit("click");
},
/**
* 获取当前button的状态
* true:禁用,false:可用
*/
async loadDisabledStatus() {
const {action, product, buttonStyle} = this.buttonDct;
this.formatButtonStyle(buttonStyle);
let disabledStatus = true;
if (action && product) {
// currentActionIsDisabled为我封装的权限判断方法,在这就不展示了
disabledStatus = await currentActionIsDisabled(product, action);
}
this.disabledStatus = disabledStatus;
},
// 格式化button的风格
formatButtonStyle(bStyle) {
// 判断当前风格是否存在于button风格字典,如果存在,则设为true,反之,不做任何操作
if (this.buttonStyle.hasOwnProperty(bStyle)) {
this.buttonStyle[bStyle] = true;
}
},
},
};
</script>
2⃣️vue自定义指令--directive
第二时间想到了这个黑科技,定一个专属于项目的指令,好像是个不错的选择。
对于directive不熟悉的可以看一下官方文档,还是很详细的。传送门
思路:根据判断权限的方法返回的结果,为当前button添加class(is-disabled),当然,因为使用的是element,所以button添加的是is-disabled这个class,不过这个还是要根据各自的实际情况修改,不要照本全搬。
废话不说,上代码:
import Vue from "vue";
// currentActionIsDisabled为权限判断方法
import {currentActionIsDisabled} from "@/helpers/policy.js";
// 注册一个全局自定义指令 `v-yh-btn-muddy`
Vue.directive("yh-btn-muddy", {
// 当button无权限时,为button添加class(is-disabled)
inserted: async function(el, binding) {
const {action, product} = binding.value;
const disabled = await currentActionIsDisabled(product, action);
if (disabled) {
el.classList.add("is-disabled");
}
},
});
就是那么简单,事件的两个参数(el, binding)分别为当前节点和自定义的参数。
现在只需要挂载在全局即可:
在main.js里引入即可
import "./directives/yh-access-muddy";
到现在为止基本完成了,你可以像使用v-modal一样使用v-yh-btn-muddy了。
现在要做的是为每个button增加v-yh-btn-muddy指令,虽然也会费点精力,但相对于刚开始的实现方式,这种方式明显精简了很多。如果你有其他更好的方式,欢迎分享。
上一篇: 用户权限控制分析