开启掘金成长之旅!这是我参与「掘金日新计划 · 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',删除按钮正常显示,否则将会隐藏