在Vue中使用防抖與節流,及this指向的問題

使用防抖與節流,及this指向問題

最近項目中遇到瞭防抖與節流問題,搜索瞭很多文章都有this指向的問題,最後不得不采取一種很low的方法

data中定義isFirst為1

if (this.isFirst < 2){
    this.isFirst = 2
    setTimeout(() => {
        this.isFirst = 1
      }, 1000)
  }

這樣就形成瞭假的節流

但是我們怎麼能屈服於這種寫法

繼續探索vue項目中用閉包的方式防抖節流

一頓操作後

 const delay = (function () {
    let timeout
    return (callback, ms) => {
      if (timeout) clearTimeout(timeout)
      let callNow = !timeout
      timeout = setTimeout(() => {
        timeout = undefined
      }, ms)
      if (callNow) callback.apply(this, [callback, ms])
    }
  })()
 export default {
    methods: {
        delay(() => {
          // do something
       }, 1000)
    }
}

用瞭立即執行的函數方法,就能夠獲取到全局的this瞭 

使用防抖函數所遇見的坑

以前的防抖和節流都是在js中直接書寫,後使用vue進行組件化開發之後,有些地方需要註意。

正常寫法

    function debounce(func, delay) {
      let timeout
      return function () {
        let context = this;
        let args = arguments;
        if (timeout) {
          clearTimeout(timeout)
        }
        timeout = setTimeout(() => {
          func.apply(context, args)
        }, delay)
      }
    }

使用

    function change(volume, data) {
      debounce(() => {
        console.log('change', volume, data);
      }, 500)
    }

Vue中寫法使用

註意: Vue中使用時,需要定義timeout,同時在防抖函數中,this的指向發生瞭變化,需要在return之前獲取vue實例。這個時候,你直接使用,還是不行的,隻要debug就會發現debounce返回的func沒有進去,需要手動執行一下(添加括號)。

  data() {
    return {
      timeout: null
    }
  }
    change(volume, data) {
      this.debounce(() => {
        console.log('change', volume, data)
      }, 500)
    },
    debounce(func, delay) {
      let context = this // this指向發生變化,需要提出來
      let args = arguments
      return function () {
        if (context.timeout) {
          clearTimeout(context.timeout)
        }
        context.timeout = setTimeout(() => {
          func.apply(context, args)
        }, delay)
      }()// 註意:我加瞭()
    }

Vue中的watch的防抖簡寫

    watchObj: {
      handler(val) {
        let _this = this
        clearTimeout(this.timeout)
        this.timeout = setTimeout(() => {
          _this.handlerData(val)
        }, 500)
      }
    }

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: