前言
在开发的过程中,时常因为重用操作,而去封装组件或者自定义指令或者提取公用方法。今天重新过了一下
v2
、v3
的官网,将自定义指令部分整理到一块,以便之后的开发中,更为直观的看见其中的区别,方便开发。
自定义指令
自定义指令的定义:
- 一个包含类似组件生命周期钩子的对象。
开发自定义指令的目的:
- 为了重用涉及普通元素的底层 DOM 访问的逻辑,(说白了就是复用,一次定义,随处使用)。
- 使用方式:比较简单,在自己想用的标签上加上
v-
+自定义指令名称
,例如:‘v-highlight’
自定义指令的注册:
- 其中的钩子函数会接收到指令所绑定元素作为其参数
全局注册
- vue3
import { highlight } from '@/utils/highlight.js'
const app = createApp({})
// 使 v-highlight 在所有组件中都可用
app.directive('highlight', highlight)
- vue2
import { highlight } from '@/utils/highlight.js'
// 注册一个全局自定义指令 `v-highlight`
Vue.directive('highlight',highlight)
组件内注册
- vue3
在<script setup>
中,任何以 v 开头的驼峰式命名的变量都可以当作自定义指令使用。
<script setup>
// 在模板中启用 v-highlight
const vHighlight = {
mounted: (el) => {
el.classList.add('is-highlight')
}
}
</script>
<template>
<p v-highlight>This sentence is important!</p>
</template>
在不使用 <script setup>
时,自定义指令需要通过 directives
选项注册
export default {
setup() {
/*...*/
},
directives: {
// 在模板中启用 v-highlight
highlight: {
/* ... */
}
}
}
- vue2
在vue2
的组件中,只能使用directives
注册;
import { highlight } from '@/utils/highlight.js'
<script>
export default{
...,
directives: {
highlight
},
...
}
</script>
钩子函数
钩子名 | 调用时机 | 调用形式 |
---|---|---|
created | 在绑定元素的 attribute 前;或者事件监听器应用前调用 | created(el, binding, vnode) {} |
beforeMount | 在元素被插入到 DOM 前调用 | beforeMount(el, binding, vnode) {} |
mounted | 在绑定元素的父组件 及他自己的所有子节点都挂载完成后调用 | mounted(el, binding, vnode) {} |
beforeUpdate | 绑定元素的父组件更新前调用 | beforeUpdate(el, binding, vnode, prevVnode) {} |
updated | 在绑定元素的父组件及他自己的所有子节点都更新后调用 | updated(el, binding, vnode, prevVnode) {} |
beforeUnmount | 绑定元素的父组件卸载前调用 | beforeUnmount(el, binding, vnode) {} |
unmounted | 绑定元素的父组件卸载后调用 | unmounted(el, binding, vnode) {} |
钩子名 | 解释 |
---|---|
bind | 只调用一次,指令第一次绑定到元素时调用:应用初始化 |
inserted | 被绑定元素插入父节点时调用 |
update | 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前 |
componentUpdated | 指令所在组件的 VNode 及其子 VNode 全部更新后调用 |
unbind | 只调用一次,指令与元素解绑时调用 |
钩子参数
参数 | v3 | v2 |
---|---|---|
el | 指令所绑定的元素,可以用来直接操作 DOM | 同v3 |
binding | 1. value :传递给指令的值;2. oldValue :之前的值;3. arg :传递给指令的参数 4. modifiers :一个包含修饰符的对象5. instance :使用该指令的组件实例6. dir :指令的定义对象 | 1.name :指令名,不包括 v- 前缀2. value :指令的绑定值3. oldValue :指令绑定的前一个值4. expression :字符串形式的指令表达式5. arg :传给指令的参数6. modifiers :一个包含修饰符的对象 |
vnode | 代表绑定元素的底层 VNode | 同v3 |
oldVnode | 无 | 代表之前的渲染中指令所绑定元素的 VNode 仅在 update 和 componentUpdated 钩子中可用 |
prevVnode | 代表之前的渲染中指令所绑定元素的 VNode 仅在 beforeUpdate 和 updated 钩子中可用 | 无 |
动态指令参数
vue2
和vue3
自定义指令的参数都可以是动态的 ,如下所示:
<div v-example:[arg]="value"></div>
指令的参数会基于组件的
arg
数据属性响应式地更新除了
el
外,其他参数都是只读的,不要更改它们。若你需要在不同的钩子间共享信息,推荐通过元素的 dataset attribute 实现。
简化形式
//vue3
app.directive('color', (el, binding) => {
// 在 `mounted` 和 `updated` 时都调用
el.style.color = binding.value
})
//vue2
Vue.directive('color-swatch', function (el, binding) {
//在 bind 和 update 时触发
el.style.backgroundColor = binding.value
})
对象字面量
vue2
和vue3
自定义指令的参数可以是多个值,可以向它传递一个 JavaScript 对象字面量,同时,也可以接收任何合法的 JavaScript 表达式。
<div v-demo="{ color: 'white', text: 'hello!' }"></div>