vue模板指令封装防抖节流

·  阅读 897

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

复制代码

防抖.gif

节流测试

输入框里每次按下回车进行删除,事件执行两次的间隔时间应该大于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
复制代码

节流2.gif

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改