vue自定义指令:防抖与节流

摘要:防抖:触发事件后,一段时间内没有再次触发则执行,若此时间段内再次触发重新延时!节流一段时间内首次触发时立即执行,此时间段内再次触发,不会执行!

防抖

解释:触发事件后,一段时间内没有再次触发则执行,若此时间段内再次触发重新延时!

v-antiShake

// 实现

Vue.directive('antiShake', {
  // 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  /**
  * el 指令所绑定的元素,可以用来直接操作 DOM 。
  * binding 一个对象,包含绑定的值
  */
  
  inserted: function(el, binding) {
    const { callback, time } = binding.value
    el.callback = callback
    el.time = time
    el.timeCall = null
    el.addEventListener('click', () => {
      clearTimeout(el.timeCall)
      el.timeCall = setTimeout(() => {
        el.callback()
      }, el.time || 500)
    })
  },
  // 所在组件的 VNode 更新时调用
  update: function(el, binding) {
    console.log('update')
    const { callback, time } = binding.value
    el.callback = callback
    el.time = time
  },
})

核心原理

     const { callback, time } = binding.value
    el.callback = callback
    el.time = time
    el.timeCall = null
    el.addEventListener('click', () => {
      clearTimeout(el.timeCall)
      el.timeCall = setTimeout(() => {
        el.callback()
      }, el.time || 500)
    })

通过定时器setTimeout延时执行click回调,当el.time || 500 时间内,再次触发时 clearTimeout(el.timeCall)关闭定时器,再次重新延时

el.callback = callback 和 el.time = time 挂在el上是为了,当v-antiShake绑定的值更新后,事件触发更新后的callback

 update: function(el, binding) {
    console.log('update')
    const { callback, time } = binding.value
    el.callback = callback
    el.time = time
  },
使用

指令的值testClick未做深watch,只有对象整体改变才会触发指令中update钩子函数

 <button v-antiShake="testClick">click</button>
 
 // testClick
  testClick: {
     time: 1000,
     callback: () => {
        console.log(1111)
        console.log(this.test)
      }
  }


节流

一段时间内首次触发时立即执行,此时间段内再次触发,不会执行!

实现:

Vue.directive('throttling', {
  // 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  inserted: function(el, binding) {
    const { callback, time } = binding.value
    el.callback = callback
    el.time = time
    el.addEventListener('click', () => {
      const nowTime = new Date().getTime()
      if (!el.preTime || nowTime - el.preTime > el.time) {
        el.preTime = nowTime
        el.callback()
      }
    })
  },
  update: function(el, binding) {
    console.log('update')
    const { callback, time } = binding.value
    el.callback = callback
    el.time = time
  }
})

el.preTime 记录上次触发事件,每次触发比较nowTime(当前时间) 和 el.preTime 的差是否大于指定的时间段!


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_6034