Vue 自定义指令实现按钮级别的权限控制

在我们的日常开发过程中,通常会对菜单进行权限划分,如果粒度要求的比较细的话,还会对页面按钮进行权限划分,本次文章来介绍一下如果使用Vue的自定义指令来实现按钮级别的权限划分。

Vue:指令(directive)简介

Vue里v-modelv-show等都属于核心指令,除此之外,也可以自己写一些自定义指令。虽然和组件(components)比起来,这些属于锦上添花的小技巧,不过对于大面积的使用,抽取出一些公共方法,放到指令里,有时候能起到事半功倍的效果。

指令可以通过全局注册,也可以局部注册,这一点和组件类似。

指令提供的钩子函数:

  • bind(绑定到元素时调用)
  • unbind(解绑时调用)
  • inserted(被绑定元素插入到父节点时调用)
  • update(被绑定元素所在的模版更新时调用)
  • componentUpdate(被绑定元素所在模版完成一次更新周期时调用)。

这几个钩子函数的参数:el(指令绑定的元素)、bindingvnodeoldVnode,其中binding是个很有意思的参数。

binding 参数是一个对象,包含如下属性:

  • name:指令名,不包括 v- 前缀。
  • value:指令的绑定值。
  • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用,无论值是否改变都可用。
  • expression:绑定值的字符串形式。 例如 v-my-directive=”1 + 1″ , expression 的值是 “1 + 1″。
  • arg:传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”。
  • modifiers:一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。

我们用到的知识点,都已经有了一个简单的介绍,下面我们直接通过代码演示的方式,实现功能了。

功能实现

新建自定义指令

src/directive/permission/permisaction.js

import store from '@/store'

export default {
  inserted(el, binding, vnode) {
    const { value } = binding // 获取指令的绑定值
    const all_permission = '*:*:*' // 表示所有权限
    const permissions = store.getters && store.getters.permisaction // 从 Vuex 中获取数据

    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(`请设置操作权限标签值`)
    }
  }
}

注册指令

src/directive/permission/index.js

import permission from './permission'
import permisaction from './permisaction' // 引入

const install = function(Vue) {
  Vue.directive('permission', permission)
  Vue.directive('permisaction', permisaction) // 注册指令
}

if (window.Vue) {
  window['permission'] = permission
  window['permisaction'] = permisaction // 将自定义指令挂在到window对象上
  Vue.use(install); // eslint-disable-line
}

permission.install = install
export default permission

后端得到权限标识数据

从后端拿到权限标识数据,然后存入到 Vuex 中,方便上面的步骤调用。

src/store/modules/user.js

import { getUserPermission } from '@/api/user'

const getDefaultState = () => {
  return {
    permisaction: [] // 新增
  }
}

const state = getDefaultState()

const mutations = {
  SET_PERMISSIONS: (state, permisaction) => { // 新增
    state.permisaction = permisaction
  }
}

const actions = {
  getPermissions({ commit, state }) { // 新增
    return new Promise((resolve, reject) => {
      getUserPermission().then(res => {
        commit('SET_PERMISSIONS', res.data)
        resolve(res.data)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

src/store/getters.js

const getters = {
  permisaction: state => state.user.permisaction
}
export default getters

在这个文件 src/permission.js 添加如下内容:

Vue 自定义指令实现按钮级别的权限控制

注册指令到全局

添加一下内容:

import permission from './directive/permission'
Vue.use(permission)

本文为原创文章,未经授权禁止转载本站文章。
原文出处:兰玉磊的个人博客
原文链接:https://www.fdevops.com/2021/05/29/vue-30814
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可。

(11)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
兰玉磊兰玉磊
上一篇 2021年5月29日
下一篇 2021年7月25日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注