vue中使用节流 throttle与防抖 debounce

219 阅读1分钟

一、节流和防抖的实现方法

节流 throttle

节流可以看作「技能冷却中」
使用场景:例如用在点击按钮的时候。

const throttle = (fn, time) => {
  let timer = null
  return (...args) => {
    if (timer){ return }
    fn.call(undefined, ...args)
    timer = setTimeout(() => {
      timer = null
    }, time)
  }
}

const f = throttle(()=> {console.log('hello')}, 3000)
f() // 打印 hello 
f() // 技能冷却中

防抖 debounce

防抖可以看作「回城被打断」
使用场景:例如拖动窗口,改变页面窗口大小时。

const debounce = (fn, time) => {
  let timer = null
  return (...args) => {
    if (timer !== null){
      clearTimeout(timer) // 打断回城
    }
    timer = setTimeout(() => {
      fn.call(undefined, ...args) // 回城后调用 fn
      timer = null
    }, time)
  }
}

const f = debounce(() => { console.log('回城成功')}, 3000)
f() // 被下面的执行函数打断了
f() // 3秒后打印"回城成功"

二、在vue中应用节流和防抖

节流 throttle

举例:给button添加节流操作

<template>
  <div>
    <button @click="handleClick">按钮</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      timer: null
    }
  },
  methods: {
    handleClick() {
      this.throttle((arg1) => {
        // 在这里写要执行的方法
        console.log(arg1)
      }, 2000)('click!!')
    },
    // 节流方法代码
    throttle(fn, time) {
      return (...args) => {
        if (this.timer) return
        fn.call(undefined, ...args)
        this.timer = setTimeout(() => {
          this.timer = null
        }, time)
      }
    }
  }
}
</script>

防抖 debounce

举例:给input添加防抖操作

<template>
  <div>
    <input v-model="value" @input="handleChange">
  </div>
</template>
<script>
export default {
  data() {
    return {
      value: '',
      timer: null
    }
  },
  methods: {
    handleChange() {
      this.debounce((arg1, arg2) => { 
        // 在这里写要执行的方法
        console.log(this.value)
        console.log(arg1, arg2)
      }, 1000)('参数1', '参数2')
    },
    // 防抖方法代码
    debounce(fn, time) {
      return (...args) => {
        if (this.timer !== null) {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(() => {
          fn.call(undefined, ...args)
          this.timer = null
        }, time)
      }
    }
  }
}
</script>