当我使用
v-permission的指令时,如果当前登录的角色不是ADMIN,那么应用应该要阻止点击的后续事件。
1. 自定义组件
<script setup>
const emits = defineEmits({
action: (payload) => payload.length > 0
})
function deleted() {
console.log("删除!")
emits('action', 'delete')
}
</script>
<template>
<button @click="deleted">阻止点击事件</button>
</template>
2. 使用
<script>
function click(payload) {
console.log("删除!", payload)
}
</script>
<template>
<CustomButton v-permissions="['ADMIN']" @action="click"></CustomButton>
</template>
3. 实现(Vue3.3.5)
// main.js
app.directive('permissions', {
mounted(el, binding, vNode) {
const {getRole} = useRoleStore()
if (!Array.isArray(binding.value)) console.error('permission must be array')
if (!binding.value.includes(getRole)) return
const vei_key = Object.getOwnPropertySymbols(el)?.[0]
if (el[vei_key].onClick) {
el[vei_key].onClick.value = () => console.error('Administrator privileges are required')
}
}
})
3.3.5后vue对操作内部属性的方式进行了修复
具体的Github Issues在这里
Custom Directives do not correctly obtain Vue Event Invoker · Issue #9571 · vuejs/core (github.com)
4. 下面的为3.3.4以及以下的实现方式
// main.js
app.directive('permissions', {
mounted(el, binding, vNode) {
const {getRole} = useRoleStore()
if (!Array.isArray(binding.value)) console.error('permission must be array')
if (!binding.value.includes(getRole)) return
if (el._vei.onClick) {
el._vei.onClick.value = () => console.error('Administrator privileges are required')
}
}
})
实际上就是3.3.5将获取私有属性的_vei给包在了Symbol里
想要获取需要使用到
Object.getOwnPropertySymbols(el)?.[0]
用这种方式去拦截click的好处是我在使用自定义组件的同时依然可以使用@click事件,当该组件确实需要细粒度的控制权限时,我可以用v-permissions这种方式对组件进行扩展,而不是删除@click(如果不理解这句话,可以参考最下面的参考文章)
! 如果不仅仅是要对click进行拦截还需要可能 隐藏|换色|不可点击,那么需要再
v-permissions后面再增加参数即可。例如:
v-permissions:disabled|hidden|color... 等等。具体可以看官网的参数和修饰符: