1、概述
防抖和节流都是为了降低事件的触发频率,一般在点击、输入组件中应用比较频繁。
2、防抖
在一段时间内触发一次,再次触发重新计时,简单封装下
function debounce(fn,delay){
let timer = null //借助闭包
return function() {
if(timer){
clearTimeout(timer)
timer = setTimeout(fn,delay)
}else{
timer = setTimeout(fn,delay)
}
}
}
复制代码
3、节流
每个一段时间触发一次
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
return false
}
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
复制代码
4、应用
在业务代码中使用防抖或节流,一般是从utils或lodash封装好的方法引用过来使用,这次用自定义的模板指令来简单封装下
*
* @param {htmlDom | vueComponent} el 元素
* @param {Object} binding 对象
* @param {String} type 'debounce' | 'throttle'
* `temlate
* <button v-debounce.click="handleClick" />
* <button v-debounce.click.stop="[handleClick, 500, false]" />
* `
*/
function eventLimit(el, binding, type) {
const funcMap = {
debounce, throttle
}
const Fn = funcMap[type]
let bindingValue = binding.value
if (!Array.isArray(binding.value)) {
bindingValue = [bindingValue]
}
const [func, delay = 300, imediate = true] = bindingValue
const [, event, ...eventModifier] = binding.rawName.split('.')
el.addEventListener(event, ($event) => {
if (compileCode($event, eventModifier)) return null
if (compileEventModifier($event, eventModifier)) return null
Fn(func, delay, imediate)
})
}
复制代码
防抖测试
<template>
<input v-model="num" />
<button v-debounce.click.stop="testClick">
查询
</button>
</template>
<script>
methods: {
testClick() {
this.num += "1"
}
}
</script
复制代码
节流测试
输入框里每次按下回车进行删除,事件执行两次的间隔时间应该大于dealay,在控制台打印间隔时间来观察节流效果
<template>
<input v-model="num" v-throttle.keyup.enter="[deleteInput, funcDelay]" />
<button v-debounce.click.stop="testClick">
查询
</button>
</template>
<script>
methods: {
deleteInput() {
console.log("keydown-during-time:" + (new Date() - this.time) / 1000 + "s")
this.time = new Date()
const len = this.num.length
this.num = this.num.slice(0, len - 1) //输入框每按一次回车删除一格
},
}
</script
复制代码