目录
3、在入口文件index.ts中引入每个指令的注册方法,并暴露一个注册所有指令的方法
一、自定义指令生命周期及其参数
const vDirective = {
// 在绑定元素的 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) {}
}
指令的钩子会传递以下几种参数:
-
el
:指令绑定到的元素。这可以用于直接操作 DOM。 -
binding
:一个对象,包含以下属性。value
:传递给指令的值。例如在v-my-directive="1 + 1"
中,值是2
。oldValue
:之前的值,仅在beforeUpdate
和updated
中可用。无论值是否更改,它都可用。arg
:传递给指令的参数 (如果有的话)。例如在v-my-directive:foo
中,参数是"foo"
。modifiers
:一个包含修饰符的对象 (如果有的话)。例如在v-my-directive.foo.bar
中,修饰符对象是{ foo: true, bar: true }
。instance
:使用该指令的组件实例。dir
:指令的定义对象。
-
vnode
:代表绑定元素的底层 VNode。 -
prevVnode
:代表之前的渲染中指令所绑定元素的 VNode。仅在beforeUpdate
和updated
钩子中可用。
二、局部自定义指令写法
这里只说组合式的
在 <script setup>
中,任何以 v
开头的驼峰式命名的变量都可以被用作一个自定义指令。在下面的例子中,vFocus
即可以在模板中以 v-focus
的形式使用。
<script setup>
// 在模板中启用 v-focus
// 写法1
const vFocus = {
mounted: (el) => el.focus()
}
//写法2 函数式写法:对于自定义指令来说,一个很常见的情况是仅仅需要在 mounted 和 updated 上实现相同的行为,除此之外并不需要其他钩子。这种情况下我们可以直接用一个函数来定义指令
const vFocus = (el: any) => el.focus()
</script>
<template>
<input v-focus />
</template>
三、全局自定义指令写法
全局共享的自定义指令需要通过“单页面应用程序的实例对象”进行声明,示例代码如下:
// 注册(对象形式的指令)
app.directive('my-directive', {
/* 自定义指令钩子 */
mounted(el, binding) {
if(binding.value == 1){
el.focus()
}
}
})
// 注册(函数形式的指令)
app.directive('my-directive', (el, binding) => {
if(binding.value == 1){
el.focus()
}
})
// 用法
<template>
<input type="text" v-my-directive="1" />
</template>
模块化规范写法
1、在directives文件夹下书写所有自定义指令
2、每个自定义指令文件暴露出注册的方法
// directive1.ts
import type { App } from 'vue'
const directive1 = {
mounted() {},
updated() {}
}
// 暴露注册指令的方法
export function setDrective1(app: App) {
app.directive('directive1', directive1)
}
// directive2.ts
import type { App } from 'vue'
const directive2 = {
mounted() {},
updated() {}
}
// 暴露注册指令的方法
export function setDrective2(app: App) {
app.directive('directive2', directive2)
}
3、在入口文件index.ts中引入每个指令的注册方法,并暴露一个注册所有指令的方法
// index.ts
import type { App } from "vue";
import { setDrective1 } from "./directive1";
import { setDrective2 } from "./directive2";
export function setDirectives(app: App) {
// 加载需要的指令
setDrective1(app);
setDrective2(app);
}
4、在main.ts中引入注册所有指令的方法
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { setDirectives } from "./directives";
const app = createApp(App);
// 注册所有自定义指令
setDirectives(app);
app.mount("#app");