vue中使用防抖与节流,以及对涉及的知识点的一些理解

防抖跟节流分不清?

一张图解释:

 

函数防抖

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。(也就是直到不再触发一段时间后才触发)

运用场景:频繁触发按钮点击事件、input框搜索等等。

function debounce(func, delay) {
  let timer = null; // 计时器
  return function() {
    let context = this;
    let args = arguments;
    clearTimeout(timer); // 清除上一次计时器
    timer = setTimeout(() => { // 重新定时
      func.apply(context, args);
    }, delay);
  };
}

这里涉及到闭包以及改变this指向

闭包:这里简单的可以概括:一个函数中包含着一个函数,但是return的函数外部的代码只会执行一次,执行一次后就存入了闭包,而return的函数实际上就是debounce函数本身,每次进入的时候先找到闭包里的timer,如果找不到再去全局找,这就是闭包的一个用处(个人理解)。

为什么要重新命名this以及arguments?

首先要了解apply()和call()都是每个函数或对象都拥有的非继承的方法。

首先想很好理解和应用apply,其根本是对于this的理解。
this的三种指向:1.指向this所在函数的直接调用者,2.new的时候,指向new出来的对象,3.事件中指向当前的出发对象

这里如果要调用传过来的函数func,如果没有重新定义指向,this就会指向全局而不是func函数本身。

同时为什么要重新定义arguments?

因为func函数本身可能要接受参数,arguments就是传入的参数数组,而且个数可以不确定的传回给func。这样this跟要传给func的参数就不会分不清。

这时候再分析debounce函数的防抖原理:

进入debounce函数,定义一个计时器并保存到闭包,

定义this跟arguments,清除timer也就是让timer变null,延时执行函数func,如果多次触发,就会多次清除定时器(因为timer已经存入闭包(因为不是写在return的函数内部,且在全局打印不到),就不会重新定义(闭包的好处),就不会出现触发多次就延时执行多次的情况),直到不再触发delay时间后再执行func函数。

如何在vue中封装并使用

在units中暴露函数

export function debounce(func, wait) {
    let delay = wait || 500;
    let timer = null;
    return () => {
        let contect = this;
        let args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {

            func.apply(contect, args)
        }, delay)
    }
}

在需要的vue页面中引入

 <button @click="change()">按钮</button>


import { debounce } from "@/utils/index.js";


methods: {
     change: debounce(() => {
      console.log(1231322);
    }, 1000),
}

还有一种更简单的方法:

 <button @click="change()">按钮</button>

export default {

data() {
    return{
        timeout: null
    }
},
method: {
   change() {
       if(this.timeout){
            clearTimeout(this.timeout)
        }
        this.timeout = setTimeout(() => {
         console.log(1323)
         }, 500);
       }
     }
}

函数节流:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

运用场景:下拉加载更多(无限滚动)事件、浏览器的resize,scroll事件等等

function throttle(func,delay){
  let timer;
  let wait = delay || 1000;
  return function(){
     let context = this;
     let arg = arguments;
     if(timer){ //如果这时候timer有值了则返回,直到delay毫秒后再触发执行。
        return;
     }
     timer = setTimeout(()=>{
        func.apply(context, arguments)
         timer = null;  //这里不用使用clearTimeout,因为这个是在执行完函数后直接清除
     },wait)
  }
}

节流原理:

从上面代码可以看出,进入throttle先进行对timer进行初始化,第一次进入是没有timer的,所以直接延时执行函数,例如1000毫秒后,执行完函数,则清除timer。若触发throttle的指令还在触发,就会重新延时执行。所以节流就是如果一直触发(例如十秒内触发了一百次,但只会执行十次)。

至于在vue封装则跟防抖的一样

 <button @click="change()">按钮</button>

export default {

data() {
    return{
        timeout: null
    }
},
method: {
change() {
  if (this.timeout) {
        return
  }
   this.timeout = setTimeout(() => {
    console.log(123456);
        this.timeout = null
  }, 1000);
},

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值