一个指令定义对象可以提供如下几个钩子函数 (均为可选):
beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用。在这里你可以做一次性的初始化设置。
mounted:在挂载绑定元素的父组件时调用。
beforeUpdate:在更新包含组件的 VNode 之前调用。
提示
我们会在稍后讨论渲染函数时介绍更多 VNodes 的细节。
updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用。
beforeUnmount:在卸载绑定元素的父组件之前调用
unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次。
接下来我们来看一下在自定义指令 API 钩子函数的参数 (即 el、binding、vnode 和 prevNnode)
#动态指令参数
指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。
例如你想要创建一个自定义指令,用来通过固定布局将元素固定在页面上。我们可以像这样创建一个通过指令值来更新竖直位置像素值的自定义指令:
<div id="dynamic-arguments-example" class="demo">
<p>Scroll down the page</p>
<p v-pin="200">Stick me 200px from the top of the page</p>
</div>
const app = Vue.createApp({})
app.directive('pin', {
mounted(el, binding) {
el.style.position = 'fixed'
// binding.value is the value we pass to directive - in this case, it's 200
el.style.top = binding.value + 'px'
}
})
app.mount('#dynamic-arguments-example')
这会把该元素固定在距离页面顶部 200 像素的位置。但如果场景是我们需要把元素固定在左侧而不是顶部又该怎么办呢?这时使用动态参数就可以非常方便地根据每个组件实例来进行更新。
<div id="dynamicexample">
<h3>Scroll down inside this section ↓</h3>
<p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
const app = Vue.createApp({
data() {
return {
direction: 'right'
}
}
})
app.directive('pin', {
mounted(el, binding) {
el.style.position = 'fixed'
// binding.arg is an argument we pass to directive
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
}
})
app.mount('#dynamic-arguments-example')
结果:
点击此处实现
我们的定制指令现在已经足够灵活,可以支持一些不同的用例。为了使其更具动态性,我们还可以允许修改绑定值。让我们创建一个附加属性 pinPadding,并将其绑定到 <input type="range">。
<div id="dynamicexample">
<h2>Scroll down the page</h2>
<input type="range" min="0" max="500" v-model="pinPadding">
<p v-pin:[direction]="pinPadding">Stick me {{ pinPadding + 'px' }} from the {{ direction }} of the page</p>
</div>
const app = Vue.createApp({
data() {
return {
direction: 'right',
pinPadding: 200
}
}
})
让我们扩展我们的指令逻辑来重新计算固定元件更新的距离。
app.directive('pin', {
mounted(el, binding) {
el.style.position = 'fixed'
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
},
updated(el, binding) {
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
}
}) |