万万Vue中使用防抖Or节流还有这么多细节

万万Vue中使用防抖Or节流还有这么多细节

前言

防抖、节流函数在工作中经常用到,但是在使用的时候,经常都是按照网上CV就完成了,没去考虑很多细节性的问题,今天就来好好研究一下。

vue中防抖和节流

通常情况下,节流和防抖都是写成公共的方法,因此本文都的节流和防抖,就以公共方法为例。

目前在vue2中,有两种防抖和节流的使用方法

第一种方法加防抖和节流的方式:

javascript 复制代码
      // 正确使用示例
      handleInput: debounce((e) => {
        console.log(e);
      }, 1000),
      // 错误使用示例
      handleInput() {
        return debounce((() => {
          console.log('方法执行了');
        }), 1000)();
      },

第二种方法加防抖和节流的方式:这种方法需要在created或者mounted中去声明一个变量来存储这个方法,然后在下面的方法调用再去使用这个方法

javascript 复制代码
    mounted() {
      // 声明方法,利用一个变量存储
      this.debounceInput = debounce((e) => {
        console.log(e);
      }, 3000)
    },
    // 使用方法
    handleInput() {
    	this.debounceInput();
    },

细节

上面我们已经了解了使用的方法,那么接下来就是重头戏了,了解一下这两种写法有什么区别,首先是第一种

首先来运行一下,我在防抖内部加一个console.log语句

javascript 复制代码
export const debounce = (func, time) => {
    let timer = null;
    console.log(timer, '防抖函数内部的timer');
    return (...args) => {
        console.log(args);
        if(timer) clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(this, args)
        }, time)
    }
}

然后以正确示例的代码执行一下

javascript 复制代码
// 正确使用示例
handleInput: debounce((e) => {
	console.log(e);
}, 1000),

动图中我们可以看到,我刷新后没有执行任何操作(注意没有执行任何操作),但是debounce却执行了,这意味这什么?

这时候我们其实防抖函数已经把return 函数赋值给我们handleInput这个方法了

这时候其他我们的代码是这样的形式,这里可能会有误解那么timer这些变量哪里来,其实人家还是在util中执行我只是拿过来方便大家理解

那么从代码中我们就可以看在一开始我们debounce其实就已经把结果返回给我们了

这时候我们每次调用其实就是执行deboucne里return的内容

这时候timer也不会重复声明所以说,防抖有效,那么来测试一下

javascript 复制代码
      handleInput: debounce((e) => {
        console.log(e, 'debounce回调的方法');
      }, 1000),
      <el-input v-model="ruleForm.name" @input="handleInput"></el-input>

这里绑定了input事件,我们应该是重复触发就重新计时,如果计时1秒后没有重新触发就输出console.log

那么我们来看一下这种方法为什么不行

javascript 复制代码
      // 错误使用示例
      handleInput() {
        return debounce((() => {
          console.log(e, 'debounce回到的方法');
        }), 1000)();
      },

先看执行效果

如图所示造成如果结果的原因就是,我们每次执行handleInput都会把debounce内容全部的函数执行一次,但是我们想到仅仅的debounce内部的return的方法执行

如果红框内所示的内容,但是我们如果放到方法里直接执行显然是不行的,所以就有了第二种

第二种方法: 其实第二种方法就是在生命周期中,先把调用一次,存储到变量中然后拿到debounce返回的方法

javascript 复制代码
    mounted() {
      this.debounceInput = debounce((e) => {
        console.log('debounce回调的方法');
      }, 3000)
    },
    // 使用方法
    handleInput() {
    	this.debounceInput();
    },

这里我们看一下效果

可以看到防抖的效果还是有的(我这里设置了3秒后回调)

那么我们来看一下debounceInput里的内容是什么

scss 复制代码
(...args) => {
    // console.log(args);
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(undefined, args);
    }, time);
  }

结果也如我们所料

那么两种方法有什么区别吗?

其实两个区别只有一个第一种在debounce的时候无法访问this

如果说debounce需要访问当前this的时候就无法访问,同时time也是固定的

我将代码改成以下形式

javascript 复制代码
      handleInput: debounce((e) => {
        console.log(e, 'debounce回到的方法');
      }, this.delay),

运行就报错了,所以如果说需要在debounce中访问this或者当前组件的变量,推荐使用第二种方法

相关推荐
天天扭码7 小时前
如何实现流式输出?一篇文章手把手教你!
前端·aigc·ai编程
前端 贾公子7 小时前
vue移动端适配方案 === postcss-px-to-viewport
前端·javascript·html
GISer_Jing8 小时前
AI营销增长:4大核心能力+前端落地指南
前端·javascript·人工智能
明远湖之鱼8 小时前
一种基于 Service Worker 的渐进式渲染方案的基本原理
前端
前端小端长9 小时前
Vue 中 keep-alive 组件的原理与实践详解
前端·vue.js·spring
FeelTouch Labs9 小时前
Nginx核心架构设计
运维·前端·nginx
雪球工程师团队9 小时前
别再“苦力”写后台,Spec Coding “跑” 起来
前端·ai编程
m0_471199639 小时前
【场景】前端怎么解决离线收银、数据同步异常等场景问题
前端·javascript
Curvatureflight10 小时前
前端性能优化实战:从3秒到300ms的加载速度提升
前端·人工智能·性能优化