vue除了一些内置的指令外,还允许自定义指令,在 <script setup>
中,任何以 v
开头的驼峰式命名的变量都可以被用作一个自定义指令。在模板中以 v-focus
的形式使用。
自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。
只有当所需功能只能通过直接的 DOM 操作来实现时,才应该使用自定义指令。其他情况下应该尽可能地使用 v-bind
这样的内置指令来声明式地使用模板,这样更高效,也对服务端渲染更友好。
以下为自动聚焦的例子:
<template>
<input v-fouse />
</template>
<script setup lang="ts">
// 在模板中定义指令
const vFouse = {
mounted: (el: HTMLInputElement) => el.focus()
}
</script>
将一个自定义指令注册到应用层级方式:
const app = createApp({})
// 使 v-focus 在所有组件中都可用
app.directive('focus', {
/* ... */
})
指令钩子
<template>
<input v-fouse2 />
</template>
<script setup lang="ts">
/**
* 参数类型:
* 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: 指令的实例。即 Directives 的实例。
* dir: 指令的定义对象。
*
* vnode: 代表绑定元素的底层 VNode
* prevVnode: 代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。
*/
const vFouse = {
// 在绑定元素的 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) {}
}
/**
* 简化形式
* 对于自定义指令来说,一个很常见的情况是仅仅需要在 mounted 和 updated 上实现相同的行为,除此之外并不需要其他钩子。这种情况下我们可以直接用一个函数来定义指令,
* @param el
* @param binding
*/
const vFouse2 = (el, binding) => {
el.focus();
}
</script>
对象字面量
<template>
<input v-demo="{ text: '文字' }" />
</template>
<script setup lang="ts">
import type { DirectiveBinding } from 'vue';
/**
* 如果你的指令需要多个值,你可以向它传递一个 JavaScript 对象字面量
* @param el
* @param binding
*/
const vDemo = (el: HTMLInputElement, binding: DirectiveBinding) => {
// binding.value 就是传递的对象值
el.value = binding.value.text;
}
</script>
Comments NOTHING