万万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或者当前组件的变量,推荐使用第二种方法

相关推荐
小光学长1 分钟前
基于vue框架的的流浪宠物救助系统25128(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
数据库·vue.js·宠物
阿伟来咯~27 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端32 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱35 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai44 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨1 小时前
在JS中, 0 == [0] 吗
开发语言·javascript
bysking2 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试