在vue2中我们知道可以使用自定义指令完成输入框自动获取焦点v-focus,或者使用自定义指令实现按钮权限控制等,自定义指令能使我们快捷的实现这些功能,在vue3中的set up语法糖里我们该怎么去使用自定义指令呢?
首先我们先看到官方文档介绍
除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。
我们已经介绍了两种在 Vue 中重用代码的方式:组件和组合式函数。组件是主要的构建模块,而组合式函数则侧重于有状态的逻辑。另一方面,自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。下面是一个自定义指令的例子,当一个 input 元素被 Vue 插入到 DOM 中后,它会被自动聚焦:
<script setup>
// 在模板中启用 v-focus
const vFocus = {
mounted: (el) => el.focus()
}
</script>
<template>
<input v-focus />
</template>
在 <script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令。在上面的例子中,vFocus 即可以在模板中以 v-focus 的形式使用。
将一个自定义指令全局注册到应用层级也是一种常见的做法:
const app = createApp({})
// 使 v-focus 在所有组件中都可用
app.directive('focus', {
/* ... */
})
当然在vue3自定义指令中也是有钩子函数的
const myDirective = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(el, binding, vnode, prevVnode) {
// 下面会介绍各个参数的细节
},
// 在元素被插入到 DOM 前调用
beforeMount(el, binding, vnode, prevVnode) {},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件更新前调用
beforeUpdate(el, binding, vnode, prevVnode) {},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件卸载前调用
beforeUnmount(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件卸载后调用
unmounted(el, binding, vnode, prevVnode) {}
}
以上钩子函数表示在被绑定指令元素在不同时机执行的动作
在具体项目中使用自定义指令
这里我是在src下面创建一个directives文件夹,里面分别有index.ts文件和modules文件夹,modules文件夹,由于存放不同功能的自定义指令,这里我在modules文件夹中创建一个auth.ts文件
import { useAuthStore } from '@/store/modules/auth'
import type { Directive, DirectiveBinding } from 'vue'
const auth: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const { value } = binding
const authStore = useAuthStore()
const currentPageRoles = authStore.authButtonList ?? []
if (value instanceof Array && value.length) {
const hasPermission = value.every((item) =>
currentPageRoles.includes(item),
)
if (!hasPermission) el.remove()
} else {
if (!currentPageRoles.includes(value)) el.remove()
}
},
}
export default auth
创建完成自定义指令然后全局注册,在index.ts文件中
import { App } from 'vue'
import auth from './modules/auth'
const directivesList: any = {
// Custom directives
auth,
}
const directives = {
install: function (app: App<Element>) {
Object.keys(directivesList).forEach((key) => {
// 注册所有自定义指令
app.directive(key, directivesList[key])
})
},
}
export default directives
这里可能有些对于vue3不太熟悉的朋友就会纳闷了,为什么在这里注册,难道不是应该去main.ts文件中注册?
在vue3中当app.use(插件时),会默认给插件提供一个install方法,在该方法的参数中会接受到当前项目app的实例,所以可以直接在插件中的install方法中进行自定义指令全局注册,全局注册组件是一样的道理
<template #tableHeader="scope">
<el-button
type="primary"
icon="Plus"
v-auth="['btn.User.add']"
@click="openDrawer('新增')"
>
添加
</el-button>
在项目中使用