Vue项目中使用防抖和节流

原文鏈接:https://juejin.cn/post/7006257717820162056

一、防抖(debounce)

1.触发高频事件后n秒内函数只会执行一次,如果在n秒内高频事件再次被触发,则重新计算时间。

简单的说也就是一定时间段的无论点击多少次,只会执行最后一次的调用。前面的会被清除

2.在methods中直接实现
debounce (func, delay = 1000, immediate = false) {
  //闭包
  let timer = null
  //不能用箭头函数
  return function () {
    if (timer) {
      clearTimeout(timer)
    }
    if (immediate && !timer) {
      func.apply(this,arguments)
    }
    timer = setTimeout(() => {
      func.apply(this,arguments)
    }, delay)
  }
},
3.使用
<template>
  <el-input v-model="text" @input="debounceInput" />
</template>

<script>
  export default {
    mounted () {
      this.debounceInput = this.debounce(this.handle, 1000,false)
    },
    data () {
      return {
        text: '',
        debounceInput: () => {},
      }
    },

    methods: {
      handle (value) {
        console.log(value)
      },

      debounce (func, delay = 1000, immediate = false) {
        let timer = null
        //不能用箭头函数
        return function () {
          //在时间内重复调用的时候需要清空之前的定时任务
          if (timer) {
            clearTimeout(timer)
          }
          //适用于首次需要立刻执行的
          if (immediate && !timer) {
            func.apply(this,arguments)
          }
          timer = setTimeout(() => {
            func.apply(this,arguments)
          }, delay)
        }
      },
    }
  }
</script>

二、节流(throttle)

1.触发高频事件后,但在n秒内函数只会执行一次

简单的说也就是一定时间内的无论点击多少次,都只会执行第一次,其余的直接return

2.在utils.js中实现(时间戳版本)
export const throttle = (fn, delay = 1000) => {
  //距离上一次的执行时间
  let lastTime = 0
  return function () {
    let _this = this
    let _arguments = arguments
    let now = new Date().getTime()
    //如果距离上一次执行超过了delay才能再次执行
    if(now - lastTime > delay){
      fn.apply(_this,_arguments)
      lastTime = now
    }
  }
}
3.在vue中引入使用
<template>
  <el-input v-model="text" @input="throttleInput" />
</template>

<script>
  import {throttle} from '../utils'
  export default {
    name: 'throttle',
    data () {
      return {
        text: '',
      }
    },
    methods: {
      handle (value) {
        console.log(value)
      },

      throttleInput: throttle(function (...args) {
        this.handle(...args)
      })

    }
  }
</script>

三、节流的优化

上一次执行和下一次用户操作的时间差在delay内的话,这个操作就会被废弃,所以我们需要在这个时间段内生成一个timer去保证这个操作是会执行的,如果超过delay时间的话可以直接执行。

export const throttle = (fn, delay = 2000) => {
  let lastTime = 0, timer = null

  return function () {
    let _this = this
    let _arguments = arguments
    let now = new Date().getTime()
    clearTimeout(timer)
    // 判断上次触发的时间和本次触发的时间差是否小于delay,创建一个timer
    if (now - lastTime < delay) {
      timer = setTimeout(function () {
        lastTime = now
        console.log("执行器触发")
        fn.apply(_this, _arguments)
      }, delay)
    } else {
      // 否则可以直接执行
      lastTime = now
      console.log("直接触发")
      fn.apply(_this, _arguments)
    }
  }
}

四、最后:闭包

之前有接触过闭包这个概念,但是这个直译让人摸不着头脑,而且各种解释又比较繁杂,现在自己实现了一遍才了解到什么是闭包。
用java来举个不严谨的栗子,闭包就是:一个private变量,我们可以通过一个公开的方法去访问它。
Vue项目中使用防抖和节流_第1张图片

你可能感兴趣的:(vue.js,前端,javascript)