首先vue3自定义指令钩子函数发生变化,vue2的写法在vue3中不支持。
vue2中钩子函数:
inserted: 被绑定元素插入父节点时调用。
update:所用组件的VNode更新时调用,但是可能发生在其子 VNode 更新之前。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
vue3中的钩子函数 :
vue3中自定义指令钩子函数和vue2中的组件生命周期相似,区别在于钩子函数携带参数。
函数及参数如下代码:
const myDirective = {
// 在绑定元素的 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) {}
}
vue2和vue3的参数是一样的,包括(el,binding,vnode,preVNode(oldVNode)。具体用法可以查看官网。
vue2地址:https://cn.vuejs.org/v2/guide/custom-directive.html
vue3地址:https://staging-cn.vuejs.org/guide/reusability/custom-directives.html
官网上的例子如下:
vue2写法如下:
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: (el)=> {
// 聚焦元素
el.focus()
}
})
vue3写法:
// 注册一个全局自定义指令 `v-focus`
app.directive('focus', {
mounted: (el)=> {
el.focus()
}
})
实现一个防抖指令。首先实现防抖函数如下:
//利用闭包变量长期存储的特性,存储变量timer
function debounce(fn,delay){
let timer;
return function (...args){
// 有定时器则清除定时器
if(timer) clearTimeout(timer)
timer = setTimeout(()=>{
fn.apply(this,args)
},delay)
}
}
然后实现自定义防抖指令:
全局批量注册自定义指令,可以这样写。
import 。。。
const directives={
focus,
copy,
debounce
...
}
export default{
// vue官网有说,想使用Vue.use或者app.user(plugin),如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传 入。
install(Vue,options){
Object.keys(directives).forEach(item=>{
Vue.directive(item,directives[item])
})
}
}
vue2写法:
const debounce = {
inserted: function (el, binding) {
// el 就是dom节点
let timer
el.addEventListener('click', () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
binding.value()
}, 1000)
})
},
}
export default debounce
vue3的写法
const debounce = {
mounted: (el, binding) => {
let timer
el.addEventListener('click', () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
binding.value()
}, 1000)
})
},
}
export default debounce