自定义指令 断裂
概述
指令的钩子函数已重命名,以更好地与组件生命周期保持一致。
此外,expression
字符串不再作为 binding
对象的一部分传递。
2.x 语法
在 Vue 2 中,自定义指令是通过使用下面列出的钩子来创建的,这些钩子用于定位元素的生命周期,所有这些钩子都是可选的
- bind - 指令绑定到元素后调用一次。仅调用一次。
- inserted - 元素插入父 DOM 后调用一次。
- update - 当元素更新时调用此钩子,但子元素尚未更新。
- componentUpdated - 当组件和子元素更新后调用此钩子。
- unbind - 指令移除后调用此钩子。也仅调用一次。
以下是一个示例
html
<p v-highlight="'yellow'">Highlight this text bright yellow</p>
js
Vue.directive('highlight', {
bind(el, binding, vnode) {
el.style.background = binding.value
}
})
在这里,在此元素的初始设置中,指令通过传入一个值来绑定一个样式,该值可以通过应用程序更新为不同的值。
3.x 语法
然而,在 Vue 3 中,我们为自定义指令创建了一个更具凝聚力的 API。如您所见,它们与我们的组件生命周期方法大不相同,即使我们正在挂钩到类似的事件。我们现在将它们统一如下
- created - 新的!这在元素的属性或事件监听器应用之前调用。
- bind → beforeMount
- inserted → mounted
- beforeUpdate: 新的!这在元素本身更新之前调用,就像组件生命周期钩子一样。
- update → 已移除!与
updated
有太多相似之处,因此这是多余的。请改用updated
。 - componentUpdated → updated
- beforeUnmount: 新的!类似于组件生命周期钩子,这将在元素卸载之前调用。
- unbind -> unmounted
最终的 API 如下所示
js
const MyDirective = {
created(el, binding, vnode, prevVnode) {}, // new
beforeMount() {},
mounted() {},
beforeUpdate() {}, // new
updated() {},
beforeUnmount() {}, // new
unmounted() {}
}
生成的 API 可以像这样使用,反映了前面的示例
html
<p v-highlight="'yellow'">Highlight this text bright yellow</p>
js
const app = Vue.createApp({})
app.directive('highlight', {
beforeMount(el, binding, vnode) {
el.style.background = binding.value
}
})
现在,自定义指令生命周期钩子与组件本身的钩子相匹配,因此它们更容易理解和记忆!
边缘情况:访问组件实例
通常建议将指令保持独立于它们所使用的组件实例。从自定义指令中访问实例通常表明指令本身应该是一个组件。但是,在某些情况下,这实际上是有意义的。
在 Vue 2 中,必须通过 vnode
参数访问组件实例
js
bind(el, binding, vnode) {
const vm = vnode.context
}
在 Vue 3 中,实例现在是 binding
的一部分
js
mounted(el, binding, vnode) {
const vm = binding.instance
}
警告
使用 片段 支持,组件可能具有多个根节点。当应用于多根组件时,自定义指令将被忽略,并且会记录警告。