自定义指令
基本使用
一个自定义指令由一个 包含类似组件生命周期钩子的对象 来定义。指令钩子函数会接收到指令所绑定元素作为其参数。
命名规范
自定义指令在 <script setup>
中以 v
开头的驼峰式命名,但在 <template>
模板中习惯以 -
中划线方式命名。
vue
<template>
<div v-highlight="isHighlight">这是被高亮的语句1</div>
<div v-highlight="true">这是被高亮的语句2</div>
</template>
<script setup lang="ts">
import { ref, type DirectiveBinding } from "vue"
const isHighlight = ref<boolean>(true)
const vHighlight = {
mounted: (el: HTMLElement, binding: DirectiveBinding) => {
// 严格校验 binding.value 的值,防止类型错误
if (typeof binding.value !== "boolean") {
console.warn("[Vue Warning]: The value of the custom directive 'vHighlight' must be of type boolean.")
return
}
if (binding.value) {
el.classList.add("is-highlight")
}
}
}
</script>
<style scoped>
.is-highlight {
color: red;
}
</style>
vue
<template>
<div v-highlight="isHighlight">这是被高亮的语句1</div>
<div v-highlight="true">这是被高亮的语句2</div>
</template>
<script lang="ts">
import { ref, type DirectiveBinding } from "vue"
export default {
setup() {
const isHighlight = ref<boolean>(false)
return {
isHighlight
}
},
directives: {
highlight: {
mounted: (el: HTMLElement, binding: DirectiveBinding) => {
if (typeof binding.value !== "boolean") {
console.warn(
"[Vue Warning]: The value of the custom directive 'vHighlight' must be of type boolean."
)
return
}
if (binding.value) {
el.classList.add("is-highlight")
}
}
}
}
}
</script>
<style scoped>
.is-highlight {
color: red;
}
</style>
或者可以将 自定义指令 全局注册到应用层级:
ts
const app = createApp(App)
// 全局注册自定义指令
app.directive("highlight", {
mounted: (el: HTMLElement, binding: DirectiveBinding) => {
if (typeof binding.value !== "boolean") {
console.warn(
"[Vue Warning]: The value of the custom directive 'vHighlight' must be of type boolean."
)
return
}
if (binding.value) {
el.classList.add("is-highlight")
}
}
})
app.mount("#app")
对象字面量
如果你的指令需要多个值,你可以向它传递一个 JavaScript 对象字面量。
vue
<template>
<div v-highlight="{ color: 'red', backgroundColor: 'green' }">
这是被高亮的语句2
</div>
</template>
<script setup lang="ts">
import { type DirectiveBinding } from "vue"
const vHighlight = {
mounted: (el: HTMLElement, binding: DirectiveBinding) => {
// 心思缜密一些,typeof null 也是 object
if (typeof binding.value !== "object" && binding.value !== null) {
console.warn(
"[Vue Warning]: The value of the custom directive 'vHighlight' must be of type object."
)
return
}
if (binding.value) {
el.style.color = binding.value?.color
el.style.backgroundColor = binding.value?.backgroundColor
}
}
}
</script>