在vue2.x中,防抖和節(jié)流一般是通過引入防抖函數(shù)debounce
和節(jié)流函數(shù)throtte
,對(duì)事件回調(diào)進(jìn)行一層包裹,然后在模板中綁定包裹后的事件回調(diào),這樣每個(gè)需要用的地方都需要進(jìn)行防抖,節(jié)流函數(shù)的導(dǎo)入,事件回調(diào)的包裹,比較麻煩。通過摸索,有以下兩種方法。
重寫Vue.protyoep.$on方法
通過重寫Vue.prototype.$on方法,統(tǒng)一對(duì)xx事件進(jìn)行防抖和節(jié)流,(沒試過,應(yīng)該可行)
偽代碼如下:
const oldOn = Vue.prototype.$on
Vue.prototype.$on = function(...args){
const event = args[0]
let fn = args[1]
if(某某條件){
fn = debounce(fn)
// fn = throttle(fn)
}
oldOn.call(this,fn)
}
通過指令包裹vnode的存放回調(diào)
使用方法,只需要在組件或者dom元素上對(duì)需要防抖或者節(jié)流的事件添加以下指令即可
v-debounce:事件.毫秒數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-621099.html
<input @click="fn" v-debounce:click.300 v-debounce:change.300 />
實(shí)現(xiàn)細(xì)節(jié)文章來源地址http://www.zghlxwxcb.cn/news/detail-621099.html
/**
* 防抖函數(shù)
* @param {*} fn
* @param {*} wait 防抖間隔
* @param {*} immediate 立即執(zhí)行
* @returns
*/
function debounce(fn, wait = 300, immediate = true) {
let t = null
let canChangeImmdiate = !!immediate
if (typeof fn !== "function") {
throw new TypeError("debounce 第一個(gè)參數(shù)必須是函數(shù)")
}
return function debounceFn(...args) {
t && clearTimeout(t)
if (immediate) {
if (!t) {
fn.apply(this, args)
immediate = false
}
} else {
t = setTimeout(() => {
fn.apply(this, args)
if (canChangeImmdiate) {
immediate = true
t = null
}
}, wait)
}
}
}
// 直接添加在組件或者元素上 v-debounce:click.300 v-debounce:change.300 300ms
// vue2.6.x在update中,vue2.7.x在insertd鉤子中起作用
Vue.directive("debounce", {
update(el, bind, vnode) {
// 默認(rèn)給click事件添加防抖
const { value: fn, arg = "click", modifiers } = bind
const { immediate = false } = modifiers
const modNumKeys = Object.keys(modifiers).filter((key) => !isNaN(+key))
const wait = modNumKeys.length > 0 ? modNumKeys[0] : 300
if (vnode.componentInstance) {
// 組件
for (const [evtName, handlers] of Object.entries(vnode.componentInstance._events)) {
if (arg == evtName) {
vnode.componentInstance._events[evtName] = handlers.map((handler) =>
debounce(handler, wait, immediate)
)
}
}
} else {
// dom元素
for (const [evtName, handler] of Object.entries(vnode.data.on)) {
if (evtName == arg) {
if (Array.isArray(vnode.data.on[arg].fns)) {
vnode.data.on[arg].fns = vnode.data.on[arg].fns.map((fn) =>
debounce(fn, wait, immediate)
)
} else {
console.log(wait, immediate)
vnode.data.on[arg].fns = debounce(vnode.data.on[arg].fns, wait, immediate)
}
}
}
}
}
})
到了這里,關(guān)于vue2.x通過指令實(shí)現(xiàn)v-debounce和v-throttle防抖節(jié)流的實(shí)現(xiàn),親測可用。的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!