Vue2 使用自定义指令(directive)实现按钮权限

580 阅读3分钟

最近公司在招前端开发工程师,我经常会问面试者的两个问题:路由权限按钮权限实现方案,大部分人用的都是后台返回的权限标识去使用v-ifv-show判断,虽然说可以实现,但是每个页面都需要写很多代码,例如includessome等等。

大部分人都知道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注册全局自定义事件。

第三步:在元素上绑定自定义事件。

第四步:通过逻辑代码判断这个用户应不应该显示此按钮,如果应该就不做任何操作,如果不应该则删除此元素。


实现方法:

    // 通过后端接口得到的权限标识
    {
        code200
        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-vuevue-beautiful-adminiview-admin-vue,都有自己的方案。重要的不是代码怎么写,主要是一个思路。运用vue的特性以及vue自带的一些钩子和项目的需求去完成。

参考资料:Vue中directive的使用