vue 自定义指令防抖和节流

 v-throttle

 Vue 自定义指令 v-throttle 旨在实现一个“节流”功能,节流意味着在一段时间内只触发一次函数,而不是在连续触发事件时阻止事件处理函数的执行。

这里使用了闭包来存储上一次触发事件的时间,并在距离上次触发超过一定时间后才执行回调函数:



javascript
Vue.directive('throttle', {  
  bind: (el, binding, vnode) => {  
    let throttleTime = binding.value || 2000; // 节流时间,如果用户未设置则默认为2s  
    let lastRun = 0;  
  
    el.addEventListener('click', (event) => {  
      const now = new Date().getTime();  
      if (now - lastRun >= throttleTime) {  
        // 如果距离上次执行的时间超过了节流时间,则执行方法  
        lastRun = now;  
        // 触发事件绑定的方法  
        vnode.context[vnode.data.on.click](event);  
      }  
    }, true);  
  },  
});  
  
// 在模板中使用自定义指令  
<button @click="sayHello" v-throttle="1500">提交</button>

在上面的代码中,我使用了 vnode.context[vnode.data.on.click] 来调用绑定在 @click 上的方法。这通常是一个合理的做法,因为它能够确保我们调用的是 Vue 实例上的正确方法。但是,请注意,如果 sayHello 方法不是定义在 Vue 实例上,而是定义在某个组件的方法中,那么这种方法可能不起作用。

此外,我还添加了一个 throttleTime 的默认值,并允许用户通过指令值(v-throttle="1500")来覆盖这个默认值。

最后,true 作为第三个参数传递给 addEventListener 是为了在捕获阶段处理事件,这通常不是必要的,除非你有特定的理由需要在捕获阶段处理点击事件。在大多数情况下,冒泡阶段就足够了。

如果你想要的是防抖(debounce)效果(即,在一段时间内多次触发事件后,只在最后一次触发后的一段时间内执行一次方法),则需要使用不同的逻辑。

v-debounce 

要实现防抖(debounce)效果的 Vue 自定义指令,你可以使用闭包来包裹一个定时器,确保在指定的等待时间内多次触发事件时,只有最后一次触发后经过指定时间才会执行回调函数。以下是防抖自定义指令的实现:

Vue.directive('debounce', {  
  bind: function (el, binding, vnode) {  
    let debounceTime = binding.value || 2000; // 防抖时间,用户若未设置则默认为2s  
    let timer = null;  
  
    // 封装防抖函数  
    function debounceHandler(event) {  
      if (timer) {  
        clearTimeout(timer); // 清除之前的定时器  
      }  
      timer = setTimeout(function () {  
        // 在防抖时间结束后执行回调函数  
        vnode.context[vnode.data.on.click](event);  
        timer = null; // 执行后清除定时器  
      }, debounceTime);  
    }  
  
    // 为元素添加事件监听器  
    el.addEventListener('click', debounceHandler);  
  
    // 当元素卸载时,清除定时器  
    el._debounceHandler = debounceHandler;  
    vnode.context.$once('hook:beforeDestroy', function () {  
      el.removeEventListener('click', el._debounceHandler);  
      if (timer) {  
        clearTimeout(timer);  
      }  
    });  
  },  
});  
  
// 在模板中使用自定义指令  
<button @click="sayHello" v-debounce="1500">提交</button>

在这个例子中,我们定义了一个 debounceHandler 函数,它使用 setTimeout 来实现防抖逻辑。当点击事件被触发时,如果定时器 timer 已经存在,我们就清除它,并设置一个新的定时器。当定时器结束时,我们执行绑定在 @click 上的方法。

此外,我们还为元素添加了一个 _debounceHandler 属性来存储防抖处理函数,并在组件销毁前(beforeDestroy 钩子)移除事件监听器并清除定时器,以避免内存泄漏。

注意,在实际应用中,你可能需要根据具体的场景和需求来调整防抖逻辑,比如考虑在防抖期间是否允许执行回调,或者是否需要在防抖期间阻止事件的进一步传播等。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值