Vue中使用防抖或节流及监听事件addEventListener时防抖或节流

1.首先,需要先写好一个防抖函数或节流函数

// 防抖函数
export function debounce(fn, delay){
  let timeout = null
  return function(){
    let args = arguments
    if(timeout) window.clearTimeout(timeout)
    timeout = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}
// 节流函数
export function throttle(fn, delay){
  let timeout = null
  return function(){
    let args = arguments
    if(!timeout){
      timeout = setTimeout(() => {
        timeout = null
        fn.apply(this, args)
      }, delay)
    }
  }
}

 

然后,在vue文件中引用,并调用:

methods: {
  handleClick(){
    this.debounce(this)
  },
  debounce: debounce((vm) => {
    // do something,这里this不指向Vue实例,用vm传入
  }, 1000),
}

 

节流同理。

2.如果要在监听某个事件的时候使用,这时候大致差不多:

mounted(){
  let self = this
  window.addEventListener('scroll',this.scroll.bind(this, self))
},
methods: {
  scroll: throttle((self) => {
    // 用bind就可以给箭头函数传参,不用bind则这里不能用箭头函数
    var body = document.body  // 获取滚动条的dom
    var scrollTop = body.scrollTop || window.pageYOffset
    var windowHeight = body.clientHeight
    var scrollHeight = body.scrollHeight
    if(scrollTop+windowHeight>=scrollHeight){
      self.scrollBottom = true
    }else{
      self.scrollBottom = false
    }
  },300)
}

这里需要注意的是this的指向,一般来说当函数内使用箭头函数时此时函数内的this指向最近的函数this指向,即指向window,使用普通函数function时指向调用它的对象;

在addEventListener中有所不同,window.addEventListener('scroll') 中,一般来说箭头函数指向最近的this指向,是window,普通函数指向调用它的对象,也是window;

但是在Vue中不是这样,使用箭头函数时,指向undefined,而普通函数指向 Vue实例, 我想原因在于这里的scroll是一个匿名函数,在Vue中是处于严格模式的,所以指向undefined,而普通函数则处在Vue实例中,所以指向Vue实例;

所以如果要使用箭头函数,而且已知箭头函数的指向不能被bind、call、apply改变,而函数内需要使用Vue实例,那么就可以考虑为函数传参,在考虑这里只是需要传参,不能执行函数,所以只能用bind,就如上代码所示。

 

所以这里有两种写法,最后,别忘了在销毁组件前移除事件监听,否则会造成内存泄露。

 

posted @ 2020-01-16 17:18  lisiyuan  阅读(4248)  评论(0编辑  收藏  举报