vue中的防抖和节流(应用实例加分析,拒绝千篇一律)

13 篇文章 2 订阅

函数防抖(debounce):当持续触发函数时,函数不执行,间隔一段时间后再执行。 防抖即防止抖动,这里的函数防抖时防止函数多次执行,抖动时高频率且无规律的,如果高频率的触发函数势必会对性能造成影响,因此,为防止高频触发函数,我们要做函数防抖处理,举个例子:input的输入,每次input输入后都需要去数据库比对当前输入的值是否存在,用户一直在输入,如果每次输入就要去数据库比对那触发就太频繁了,为此我们可以加防抖,当用户不再输入后间隔一段时间再去执行相应的函数。

函数节流(throttle):当持续触发函数时,保证一段时间内只执行一次函数。节流即节省流量,比如水龙头放水,把水龙头关小,水流量就会降低,这样就能保证即放水又不会浪费。举个例子:scroll事件,用户下拉加载数据,一直刷新,一秒钟操作了十回,但一秒钟内只执行一回,这样保证一秒钟时间内,至少执行了一回,又不频繁触发函数。

以上就是函数防抖和节流的大致介绍,刚开始接触防抖和节流觉得很高大上,后来看了一些博客介绍之后有了自己的理解,我觉得结合实际例子来理解概念会更容易一些,将这些应用到我们的功能开发中,更能理解其用处和含义。

vue中的函数防抖,看了很多博客,都是直接贴的代码,不是特别容易理解,我就针对自己在项目中用到的情况,简单写一下,比想象中的要简单,一起来看看吧。

函数防抖

实际应用:input输入,每次输入值之后去数据库比对是否存在,当不输入后一段时间再执行函数。这里省略了函数,只打印input的值。

在这里插入图片描述

<template>
  <div style="margin: 20px;">
    <el-input v-model="inputVal"/>
  </div>
</template>

<script>
export default {
  name: 'Test',
  data() {
    return {
      inputVal: '',
      timer: null
    }
  },
  watch: {
    inputVal() {
      if (this.timer) {
        clearTimeout(this.timer)
      }
      this.timer = null
      this.timer = setTimeout(() => {
        this.handleJudge()
      }, 1000)
    }
  },
  methods: {
    handleJudge() {
      console.log(this.inputVal)
    }
  }
}
</script>

我们现在来分析一下,其实防抖就是为了不再触发后一段时间内再执行,核心在于定时器的应用,每次触发函数,清空定时器,直到不再触发函数后,间隔1000ms,执行定时器内的函数。

函数节流

实际应用:按钮的点击,用户短时间内多次点击,只执行一次点击函数。

在这里插入图片描述

<template>
  <div style="margin: 20px;">
    <el-button @click="handleClick()">click</el-button>
  </div>
</template>

<script>
export default {
  name: 'Test',
  data() {
    return {
      timer2: null,
      switchFlag: true
    }
  },
  methods: {
    handleClick() {
      if (!this.switchFlag) {
        return
      }
      this.switchFlag = false
      this.timer2 = setTimeout(() => {
        console.log('节流示例')
        this.switchFlag = true
      }, 1000)
    }
  }
}
</script>

我们现在来分析一下,其实节流就是一段时间内只执行一次函数,期间多次执行都不予以处理,实现这个功能我们需要定义一个开关和一个定时器,默认开关为开,执行一次函数后,开关置为关,再次执行,判断开关状态,为关则返回,不再向下执行,定时器1000ms后,触发函数,并把开关置为开,回到一开始的状态。

以上是函数防抖和节流的针对性应用,在一个项目中我们这样用肯定是不行的,所以还要封装成公用方法,精简我们的代码,下面贴2段经典常用的防抖和节流的代码。

/**
 * 函数防抖 (只执行最后一次点击)
 * @param fn
 * @param delay
 * @returns {Function}
 * @constructor
 */
export const Debounce = (fn, t) => {
  let delay = t || 500
  let timer
  return function () {
    let args = arguments
    if(timer){
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      timer = null
      fn.apply(this, args)
    }, delay)
  }
};
/**
 * 函数节流
 * @param fn
 * @param interval
 * @returns {Function}
 * @constructor
 */
export const Throttle = (fn, t) => {
  let last
  let timer
  let interval = t || 500
  return function () {
    let args = arguments
    let now = +new Date()
    if (last && now - last < interval) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        last = now
        fn.apply(this, args)
      }, interval)
    } else {
      last = now
      fn.apply(this, args)
    }
  }
}

具体到vue中使用的话,将2个方法放到公用方法的js里,并导出,应用如下:

<template>
  <div style="margin: 20px;">
    <input v-model="keyword" type="text" @keyup="appSearch">
  </div>
</template>
<script>
import { Debounce } from '@/commonFunction/common'
export default {
  name: 'Test',
  data() {
    return {
      keyword: ''
    }
  },
  methods: {
    appSearch: Debounce (function() {
      this.getAppList()
    }, 1000),
    getAppList() {
      console.log(this.keyword)
    }
  }
}
</script>

最一开始查询有关防抖和节流的时候,出现的都是直接贴代码的帖子,并且都没有分析,可能也是自己基础比较欠缺,趁此又补充了一波,挺好。我们来分析一下防抖经典示例中的代码。

export const Debounce = (fn, t) => {
  let delay = t || 500
  let timer
  return function () {
    let args = arguments
    if(timer){
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      timer = null
      fn.apply(this, args)
    }, delay)
  }
};

不知道是不是有很多人和我一样 fn.apply(this,args) 看不懂,为此,我查了关于arguments的相关资料,又查了apply相关的资料,终于在MDN上找到了回答,MDN上关于apply的用法有这样一段。
在这里插入图片描述
在这里插入图片描述

好好看几遍这段话,调用函数时,为函数指定一个this对象,谁调用这个函数this就指向谁,使用apply,就可以继承不用再重复写该方法。

来到我们的例子中看一下,我一直觉得打印功能是非常棒的功能,尤其在我们并不了解某些功能和含义的时候。哪里不会打印哪里,妈妈再也不用担心我的学习。

export const Debounce = (fn, t) => {
  let delay = t || 500
  let timer
  return function () {
    let args = arguments
    if(timer){
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      timer = null
      fn.apply(this, args)
      console.log(fn)
      console.log(this)
      console.log(args)
    }, delay)
  }
};

我们分别打印 fn、this、和arguments
在这里插入图片描述

可以看到fn即为我们作为参数传入的函数,this为调用该Debounce方法的vue组件,arguments为vue中调用该Debounce方法的getAppList()函数的相关参数。

根据打印结果再结合MDN上关于apply的解释,我们可以这样认定 fn.apply(this,arguments) 的作用在于使调用Debounce函数的vue组件中的方法指向正确,this指向当前组件本身,因为我们将Debounce写成了公共方法,因此会被多个组件调用,这样this的指向就不明确了,为了保证this都是指向当前调用Debounce函数的组件自身而将this绑定到调用的组件上,说白了就是一句话,哪个组件调用方法,this就指向哪个组件。

在这里插入图片描述

关于防抖和节流的细节分析已经有很多博客了,这里就不再说了,里边还涉及很多知识点,在下一篇博客中,针对防抖节流函数中应用到的知识点进行详细补充说明。 下面附上一篇我看过还不错的文章,可以帮助大家理解。

防抖节流

  • 15
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值