最近公司在招前端开发工程师,我经常会问面试者的两个问题:路由权限和按钮权限实现方案,大部分人用的都是后台返回的权限标识去使用v-if或v-show判断,虽然说可以实现,但是每个页面都需要写很多代码,例如includes,some等等。
大部分人都知道vue的自定义指令,但是都没有用过,也就知道有这个东西。所以我写这篇文章可以让大家了解一下Vue的自定义指令,以及其中一种按钮权限解决方案。
我们先来看看Vue directive的实例代码:
// 注册自定义函数
Vue.directive('focusDirective', {
inserted: function (el) {
// 这里可以做一些判断
}
})
// 使用自定义函数
<div v-focusDirective="true">
我们可以在inserted里面通过el这个参数去删除这个元素,也就是我们按钮权限的核心,不让某些用户展示某些按钮。 我们可以看看具体的参数:
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
一般用的比较多的就是inserted钩子较多,所以我们来看看inserted的参数:
el:指令所绑定的元素,可以用来直接操作 DOM。
binding:一个对象
vnode:Vue 编译生成的虚拟节点。
// 还有很多其他的参数 可以参考以下网址,这里不再过多介绍:
// https://blog.csdn.net/relax_go/article/details/108982258
知道了这些参数我们可以确定一个基本方案:
第一步:登录拿到用户权限标识(多个)。
第二步:main.js注册全局自定义事件。
第三步:在元素上绑定自定义事件。
第四步:通过逻辑代码判断这个用户应不应该显示此按钮,如果应该就不做任何操作,如果不应该则删除此元素。
实现方法:
// 通过后端接口得到的权限标识
{
code: 200
data: {permissions: ["*:*:*"], roles: ["admin"],…}
permissions: ["*:*:*"]
roles: ["admin"]
}
// 存进vuex里,不做多展示
// main.js文件
Vue.directive('permissions', {
inserted(el, binding){
const { value } = binding
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission)
})
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请设置操作权限标签值`)
}
}
})
// 然后在元素上使用
<el-button
type="danger"
plain
icon="el-icon-circle-close"
size="mini"
v-hasPermi="['system:role:remove']"
>删除</el-button>
整体逻辑就是:按钮上的权限system:role:remove就是我用户需要有的权限,然后我在后端返回的权限列表通过includes判断用户有没有这个权限,如果没有我就删掉这个按钮。
按钮权限.includes(用户权限Array);
这就是一套完整的按钮权限解决方案,展示和隐藏的逻辑,可以根据需求变化调整。例如加入角色等等。
总结: 按钮权限和路由权限有很多种方案,element-admin-vue,vue-beautiful-admin,iview-admin-vue,都有自己的方案。重要的不是代码怎么写,主要是一个思路。运用vue的特性以及vue自带的一些钩子和项目的需求去完成。
参考资料:Vue中directive的使用