利用功能受控指令控制功能权限

121 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情

自定义指令

Vue除了内置的一些基本指令如v-model等,还允许注册自定义的指令。一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。

局部注册

setup() {
    /*...*/
  },
  directives: {
    // 在模板中启用 v-focus
    focus: {
      /* ... */
    }
  }
}

全局注册

const app = createApp({})

app.directive('focus', {
  /* ... */
})

指令钩子

一个指令的定义对象可以提供几种可选钩子函数,钩子函数传递一些参数,详情查看自定义指令

受控指令

我们的需求是根据登陆的用户不同,控制不同的功能按钮的显示和隐藏

比如在vuex中保存了以下数据

points: [
    'distributeRole',
    'importUser',
    'removeUser',
    'distributePermission'
    ]

就是当前用户需要的按钮功能权限

我们希望的效果是自定义一个指令v-permission,如下v-permission="['distributeRole']",为每个按钮指定一个字符串,如果登录用户的points中含有该字符串,则用户有该功能的权限,否则隐藏按钮

创建受控指令

新建directives/permission.js

在mounted和update钩子中调用checkPermission函数

checkPermission函数的逻辑是获取当前的值,在获取用户的权限,如果当前的值在用户的权限中,则显示该按钮,否则将该节点移除

import store from '@/store'

function checkPermission(el, binding) {
  // 获取对应权限
  const { value } = binding
  // 获取当前用户的所有功能权限
  const points = store.getters.userInfo.permission.points
  if (value && value instanceof Array) {
    const hasPermission = points.some((point) => {
      return value.includes(point)
    })
    // 匹配失败
    if (!hasPermission) {
      el.parentNode && el.parentNode.removeChild(el)
    }
  } else {
    throw new Error('必须为数组')
  }
}
export default {
  // 绑定元素的父组件被挂载后调用
  mounted(el, binding) {
    checkPermission(el, binding)
  },
  // 在包含组件的VNode及其子组件的VNode更新后调用
  update(el, binding) {
    checkPermission(el, binding)
  }
}

接着在directives/index.js 中绑定该指令

import permission from './permission'

export default (app) => {
  app.directive('permission', permission)
}

main.js中引入

import installDirective from '@/directives/index'

installDirective(app)

接着在对应功能按钮上使用v-permission指令

比如删除按钮

<el-button
  ···
  v-permission="['distributeRole']"
  >{{ $t('msg.excel.showRole') }}</el-button
>

如果用户登陆后返回的points数组中包含'distributeRole',删除按钮正常显示,否则将会隐藏

1.png

2.png