目录全局注册自定义指令防抖1、先建一个js文件2、在mian.js里面注册3、使用Vue防抖的使用防抖函数在vue中直接使用vue中使用高阶组件vue中自定义指令使用全局注册自定义指
建一个debounce.js文件,放在src/directives文件夹里面
export default (vue) => {
vue.directive('debounce', { //防抖函数指令
inserted: function(el, binding) {
let timer;
el.addEventListener("click", () => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
//关键点:vue 的自定义指令传递的参数binding 如果是一个函数,则通过 binding.value()来执行,通过上述示例,还可以传递比如事件, 绑定对象之类的
binding.value();
}, 1000);
});
}
})
}
import Debounce from './directives/debounce.js' //防抖自定义指令
Debounce(Vue)
在组件中button按钮添加该指令即可实现防抖
v-debounce="getTableData"
function debounce(fn, immediate = true) {
let timer;
return function () {
if (timer) clearTimeout(timer);
if (immediate) {
let bool = !timer;
timer = setTimeout(() => (timer = 0), 300);
return bool && fn.apply(this, [...arguments]);
}
timer = setTimeout(() => fn.apply(this, [...arguments]), 300);
};
}
export default {
debounce,
};
import utils from "./utils/index";
methods:{
// 手动添加debounce
btnHandler1: utils["debounce"](function (...rest) {
console.log("2222 ", this, rest);
}),
}
使用抽象组件对于传入按钮进行改造,对于按钮进行事件的重写,加入防抖功能;
import Vue from 'vue'
// ctx 【context 上下文 绑定this指向】
const debounce = (func, time, ctx, immediate = true) => {
let timeout
return function (...params) {
if (timeout) clearTimeout(timeout)
if (immediate) {
var callNow = !timeout
timeout = setTimeout(() => {
timeout = null
}, time)
if (callNow) func.apply(ctx, params)
} else {
timeout = setTimeout(function () {
func.apply(ctx, params)
}, time)
}
}
}
// 只能绑定一个组件,多个组件无法绑定
Vue.component('Debounce', {
abstract: true,//抽象组件,无状态,
props: ['time', 'events', 'immediate'],
created () {
this.evenTKEys = this.events && this.events.split(',')
this.originMap = {}
this.debouncedMap = {}
},
render () {
// 组件使用proxy对象包装,可以了解 【this】;
// 取出虚拟节点,默认第一个,也就是高阶组件中若传递了多个子组件,只展示第一个
const vnode = this.$slots.default[0]
// 如果默认没有传 events,则对所有绑定事件加上防抖
if (!this.eventKeys) {
this.eventKeys = Object.keys(vnode.data.on)
}
this.eventKeys.forEach((key) => {
const target = vnode.data.on[key]
if (target === this.originMap[key] && this.debouncedMap[key]) {
vnode.data.on[key] = this.debouncedMap[key]
} else if (target) {
this.originMap[key] = target
this.debouncedMap[key] = debounce(target, this.time, vnode, this.immediate)
vnode.data.on[key] = this.debouncedMap[key]
}
})
return vnode
}
})
<Debounce events="click" time="300">
<button @click="clickHandler(1,2,3)" :btnval="'val'">click1</button>
</Debounce>
// 指令【防抖】
Vue.directive("debounce", {
// 只调用一次,第一次绑定元素时调用
// el【绑定的元素】,binding【一个相关对象】,vnode【vue编译生成的虚拟节点】
// beforemount之后,mounted之前;
// init events&lifecycle 【初始化事件和生命周期】
bind(el, binding, vnode, oldVnode) {
console.log(el, binding, vnode, oldVnode);
let { value } = binding;
let [target, time] = value;
const debounced = debounce(target, time, vnode);
el.addEventListener("click", debounced);
},
// 被绑定元素插入父节点时调用(仅保证父节点存在,但是不一定插入文档)
inserted() {},
// 所在组件的vnode更新时调用
update() {},
componentUpdated() {},
unbind(el) {
console.log(el, "el");
el.removeEventListener("click", el._debounced);
},
});
使用
<button
v-debounce="[
() => {
btnHandler();
},
300,
]"
>
点击
</button>
<button v-if="testcom" v-debounce="[btnHandler, 300]">点击</button>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
--结束END--
本文标题: vue全局注册自定义指令防抖解析
本文链接: https://lsjlt.com/news/150159.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0