最近在开发并维护公司的一个类似后台管理Vue3+TS项目。众所周知,后台项目最重要的就是关于权限的分配和判断,如页面和按钮级别的权限,遂使用自定义指令并有此小计,温故知新。
自定义指令钩子
Vue2&3在自定义指令的钩子函数中有着一定的差异。在Vue 3中,自定义指令是通过一个包含钩子函数的对象来定义的。这些钩子函数允许开发者在指令的不同生命周期阶段执行代码。选择使用哪个钩子函数取决于希望在指令的什么时机执行特定的逻辑。自定义指令Vue2版可见:Vue2指令参考。
以下是Vue 3自定义指令中可用的钩子函数及其用途:
created
:在绑定元素的attribute或v-bind表达式被应用之前调用。此时,指令的实例已经被创建,但尚未被添加到DOM中。你可以在这个钩子中设置一些初始状态或执行一些只需要在指令创建时执行一次的逻辑。beforeMount
(在Vue 2.x中是bind):在指令第一次绑定到元素上时调用。此时,元素已经被创建并添加到DOM中,但尚未进行任何渲染。你可以在这个钩子中访问DOM元素,并设置一些初始的DOM操作或事件监听器。mounted
(在Vue 2.x中是inserted):在指令所绑定的元素被插入到父节点时调用(父节点存在即可调用,不必存在于document中)。此时,元素已经被渲染并插入到DOM中。你可以在这个钩子中执行依赖于DOM的操作,如获取元素的尺寸、位置或滚动位置等。beforeUpdate
:在包含组件的VNode更新之前调用。但是,在大多数情况下,你应该避免在这个钩子中进行DOM操作,因为Vue会在之后自动更新DOM。然而,你可以在这个钩子中访问更新前的状态或props,并准备一些更新逻辑。updated
:在指令所绑定的元素的VNode及其子VNode全部更新后调用。此时,DOM已经被更新,你可以在这个钩子中执行依赖于更新后DOM的操作。beforeUnmount
(在Vue 2.x中是unbind):在指令与元素解绑之前调用。你可以在这个钩子中移除之前添加的事件监听器、清理定时器等。unmounted
:指令与元素解绑时调用(仅作为钩子函数被调用时)。你可以在这个钩子中执行一些清理工作,如移除DOM元素或清理全局状态等。
场景 | 推荐钩子函数 |
---|---|
初始化非 DOM 资源 | created |
操作 DOM 或绑定事件 | beforeMount / mounted |
获取 DOM 尺寸或文档状态相关操作 | mounted |
处理绑定值变化 | updated |
清理事件监听或全局资源 | unmounted |
一些常见的自定义指令示例如下:
v-hasPermi
:判断是否拥有该权限
export const hasPermi = {
mounted(el, binding, vnode) {
const { value } = binding // 获取v-hasPermi使用时绑定的值
const { permissions } = useUserStore() // 从store中拿到当前角色权限数组
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
return permission === '*:*:*' || value.includes(permission)
})
if (!hasPermissions) { // 如果没有该权限则移除指令所在的元素
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请检查权限信息!`)
}
}
}
v-clickOutside
:判断点击区域是否在元素之外
export const clickOutside = {
mounted(el, binding) {
el.clickHandler = (e) => {
if (!el.contains(e.target)) {
binding.value(e); // 调用传递的回调函数
}
};
document.addEventListener('click', el.clickHandler);
},
unmounted(el) {
document.removeEventListener('click', el.clickHandler); // 清理事件监听
}
};