当前位置: 首页 > news >正文

如何在 Vue 中使用 防抖 和 节流

大厂面试题分享 面试题库

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库 https://mp.weixin.qq.com/s?__biz=MzU5NzA0NzQyNg==&mid=2247485824&idx=3&sn=70cd26a7c0c683de64802f6cb9835003&scene=21#wechat_redirect

在监听频繁触发的事件时,一定要多加小心,比如 用户在输入框打字、窗口大小调整、滚动、Intersection Observer 事件。

这些事件总是被频繁触发,可能 几秒一次。如果针对每次事件都发起 fetch 请求(或类似的行为),那显然是不明智的。

我们需要做的就是减缓事件处理程序的执行速度。这种缓冲技术就是 防抖(debounce) 和 节流(throttle) 。

在本文中,你会了解到如何在 Vue 组件中 使用 防抖 和 节流 控制 观察者(watchers) 和 事件处理程序。

1. 观察者 防抖


我们先从一个简单的组件开始,我们的任务是 将用户输入到 文本框中的文本 输出到控制台:

<template><inputv-model="value"type="text" /><p>{{ value }}</p></template><script>exportdefault {data() {return {value: "",};},watch: {value(newValue, oldValue) {console.log("Value changed: ", newValue);}}
};
</script>复制代码

在 输入框 敲几个字符。每次输入时,值就会被 log 到控制台。

我们通过使用 观察者(watcher) 监听 value 数据属性 来实现了打印日志。但如果你想在 观察者的回调 中加入一个 使用 value 作为参数 的 GET 请求,那你应该不会期望太过频繁地发起请求。

我们来对 打印控制台日志 这个行为做一下 防抖。核心思想是创建一个 防抖函数,然后在 观察者 内部调用该函数。

我在这里选择了 'lodash.debounce' 的 防抖实现,但你可以自由选择喜欢的实现方式。

我们来将 防抖逻辑 应用到组件:

<template><inputv-model="value"type="text" /><p>{{ value }}</p></template><script>import debounce from"lodash.debounce";
exportdefault {data() {return {value: "",};},watch: {value(...args) {this.debouncedWatch(...args);},},created() {this.debouncedWatch = debounce((newValue, oldValue) => {console.log('New value:', newValue);}, 500);},beforeUnmount() {this.debouncedWatch.cancel();},
};
</script>复制代码

但有一个区别:只有在最后一次输入的 500ms 之后,才会将新的输入值打印日志到控制台。这说明 防抖 在生效。

观察者 的 防抖实现 只需要 3 个简单步骤:

  1. 在 create() 钩子 里,创建 防抖回调,并将其赋值到实例上:this.debouncedWatch = debounce(..., 500)。

  1. 在 观察者 回调 watch.value() { ... } 中 传入正确的参数 调用 this.debouncedWatch()。

  1. 最后,beforeUnmount() 钩子中 调用 this.debouncedWatch.cancel() ,在卸载组件之前,取消所有还在 pending 的 防抖函数执行。

采用同样的方式,你可以对任意数据属性的 观察者 应用 防抖。然后就可以安全执行 防抖回调内部的一些比较重的操作,比如 网络请求、繁重的 DOM 操作,等等。

2. 事件处理器 防抖


上面一节,我展示了如何对 观察者 使用 防抖,那么常规的事件处理器呢?

我们重用之前用户输入数据到输入框的例子,但这一次会给输入框加个 事件处理器。

像往常一样,如果你没有采取任何缓冲的措施,每当值被修改时,会被打印到控制台:

<template><inputv-on:input="handler"type="text" /></template><script>exportdefault {methods: {handler(event) {console.log('New value:', event.target.value);}}
};
</script>复制代码

在输入框打几个字符。看看控制台:你会发现每次你输入的时候就会有日志被打印出来。

同样,如果你会执行一些比较重的操作(比如网络请求),可就不合适了。

对 事件处理器 使用 防抖,可以参考下面这个:

<template><inputv-on:input="debouncedHandler"type="text" /></template><script>import debounce from"lodash.debounce";
exportdefault {created() {this.debouncedHandler = debounce(event => {console.log('New value:', event.target.value);}, 500);},beforeUnmount() {this.debouncedHandler.cancel();}
};
</script>复制代码

输入一些字符。组件只有在最后一次输入的 500ms 之后,才会将新的输入值打印日志到控制台。防抖 再一次生效了!

事件处理器 的 防抖实现 只需要 3 个步骤:

  1. . 在 create() 钩子 里,创建实例后,立刻将 防抖回调 debounce(event => {...}, 500) 赋值到 this.debouncedHandler 。

  1. 在输入框的 template 中 给 v-on:input 赋上 debouncedHandler :<input v-on:input="debouncedHandler" type="text" />

  1. 最后,在卸载组件之前, 在 beforeUnmount() 钩子中 调用 this.debouncedHandler.cancel() ,取消所有还在 pending 的 函数调用。

另一方面,这些例子应用了 防抖 的技术。然而,同样的方式可以以用于创建 节流函数。

3. 注意


你可能不理解:为什么不直接在 组件的 method 选项中创建 防抖函数,然后在 template 中调用这些方法作为事件处理器?

// ...methods: {// Why not?debouncedHandler: debounce(function () { ... }}, 500)}
// ...
复制代码

这比在实例对象上创建 防抖函数 要简单的多。

例如:

<template><inputv-on:input="debouncedHandler"type="text" /></template><script>import debounce from"lodash.debounce";
exportdefault {methods: {// Don't do this!debouncedHandler: debounce(function(event) {console.log('New value:', event.target.value);}, 500)}
};
</script>复制代码

这次不是在 created() 钩子 里创建 防抖回调了,而是将 防抖回调 赋给了 methods.debouncedHandler 。

你如果试过 demo,你会发现是有效果的!

问题是,组件使用 export default { ... } 导出的 options 对象,包括方法,会被组件实例重用。

如果网页中有 2 个以上的组件实例,那么所有的组件都会应用 相同 的防抖函数 methods.debouncedHandler — 这会导致防抖出现故障。

4. 总结


在 Vue 中,可以很轻松的对 观察者 和 事件处理器 应用 防抖 和 节流。

核心逻辑就是,在 created() 钩子 里,创建 防抖 或 节流 的回调,并赋值在实例上。

// ...created() {this.debouncedCallback = debounce((...args) => {// The debounced callback}, 500);},
// ...复制代码

A)然后在观察者内部调用实例上的防抖函数:

// ...watch: {value(...args) {this.debouncedCallback(...args);},},
// ...复制代码

B)或在 template 中设定一个事件处理器:

<template><inputv-on:input="debouncedHandler"type="text" /></template>复制代码

在这之后,每次调用 this.debouncedCallback(...args) ,就算执行频率非常高,内部的回调也能缓冲执行。

你对 Vue 中的 防抖 和 节流 还什么问题吗?欢迎提问!

大厂面试题分享 面试题库

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库 https://mp.weixin.qq.com/s?__biz=MzU5NzA0NzQyNg==&mid=2247485824&idx=3&sn=70cd26a7c0c683de64802f6cb9835003&scene=21#wechat_redirect

相关文章:

如何在 Vue 中使用 防抖 和 节流

大厂面试题分享 面试题库前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库 https://mp.weixin.qq.com/s?__bizMzU5NzA0NzQyNg&mid2247485824&idx3&sn70cd26a7c0c683de64802f6cb9835003&scene21#wech…...

美国Linux服务器系统增强安全的配置

美国Linux服务器系统可能出现的安全漏洞中&#xff0c;更多是由于不当的系统配置所造成的&#xff0c;用户们可以通过一些适当的安全配置来防止问题的发生。美国Linux服务器系统上运行的服务越多&#xff0c;不当配置的概率也就越高&#xff0c;那么系统出现安全问题的可能性也…...

【史上最全面esp32教程】oled显示篇

文章目录前言介绍及库下载基础使用引脚的连接使用函数总结前言 本节课主要讲的是OLED的基础使用。使用的oled为0.96寸&#xff0c;128*64。 大家的其他型号也是可以用的。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 介绍及库下载 oled的简介&…...

第十四届蓝桥杯三月真题刷题训练——第 21 天

目录 第 1 题&#xff1a;灭鼠先锋 问题描述 运行限制 代码&#xff1a; 思路&#xff1a; 第 2 题&#xff1a;小蓝与钥匙 问题描述 答案提交 运行限制 代码&#xff1a; 思路 : 第 3 题&#xff1a;李白打酒加强版 第 4 题&#xff1a;机房 第 1 题&#xff1…...

css绘制一个Pinia小菠萝

效果如下&#xff1a; pinia小菠萝分为头部和身体&#xff0c;头部三片叶子&#xff0c;菠萝为身体 头部 先绘制头部的盒子&#xff0c;将三片叶子至于头部盒子中 先绘制中间的叶子&#xff0c;利用border-radius实现叶子的效果&#xff0c;可以借助工具来快速实现圆角的预想…...

OpenCV入门(二十)快速学会OpenCV 19 对象测量

OpenCV入门&#xff08;二十&#xff09;快速学会OpenCV 19 对象测量1.对象测量2.多边形拟合3.计算对象中心作者&#xff1a;Xiou 1.对象测量 opencv 中对象测量包括&#xff1a; 如面积&#xff0c;周长&#xff0c;质心&#xff0c;边界框等。 弧长与面积测量&#xff1b; …...

TCP和UDP协议的区别?

是否面向连接&#xff1a; TCP 是面向连接的传输&#xff0c;UDP 是面向无连接的传输。 是否是可靠传输&#xff1a;TCP是可靠的传输服务&#xff0c;在传递数据之前&#xff0c;会有三次握手来建立连接&#xff1b;在数据传递时&#xff0c;有确认、窗口、重传、拥塞控制机制…...

【C语言蓝桥杯每日一题】——排序

【C语言蓝桥杯每日一题】—— 排序&#x1f60e;前言&#x1f64c;排序&#x1f64c;总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &#x1f60a;作者简介&am…...

学校官网的制作

学校官网 代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}.top{background-color: #3D3BB8;width: 100%;position: fixed;padding: 20px 0 12px 0;}.box{width…...

【云原生】k8s集群命令行工具kubectl之故障排除和调试命令

kubectl之故障排除和调试命令一、describe二、logs三、attach四、exec五、port-forward六、proxy七、cp八、debug8.1、案例1&#xff1a;共享进程空间8.2、案例2&#xff1a;更改启动命令、容器镜像8.3、案例3&#xff1a;调试节点8.4、其他一、describe 显示某个资源或某组资…...

AJAX,Axios,JSON简单了解

一. AJAX简介概念: AJAX(Asynchronous JavaScript And XML): 异步的JavaScript 和XMLAJAX作用:1.与服务器进行数据交换: 通过AJAX可以给服务器发送请求&#xff0c;并获取服务器响应的数据使用了AJAX和服务器进行通信&#xff0c;就可以使用 HTMLAJAX来替换JSP页面了2.异步交互…...

私域流量该如何打造?这套模式直接借鉴

梦龙商业案例分析&#xff0c;带你了解商业背后的秘密 古往今来&#xff0c;消费方与购买方的地位似乎就没有变过&#xff0c;消费者始终是处在被动接受的地位。 但到了现在&#xff0c;其实消费地位早已经不知不觉产生了改变。 就比如以前都是厂家有什么消费者买什么&#…...

【jenkins部署】一文弄懂自动打包部署(前后台)

这里写目录标题序言软件安装jdkmaven配置maven阿里镜像以及本地库位置git安装安装jenkins插件安装环境配置创建项目配置gitee生成gitee WebHookmaven打包验证是否打包成功连接远程服务器并重启服务远程服务器生成私钥配置ssh项目配置ssh脚本vue项目打包nodejs安装下载配置环境变…...

应届生投腾讯,被面试官问了8个和 ThreadLocal 相关的问题。

问&#xff1a;谈一谈ThreadLocal的结构。 ThreadLocal内部维护了一个ThreadLocalMap静态内部类&#xff0c;ThreadLocalMap中又维护了一个Entry静态内部类&#xff0c;和Entry数组。 Entry类继承弱引用类WeakReference&#xff0c;Entry类有一个有参构造函数&#xff0c;参数…...

Linux命令scp用法

本文主要讲的是scp用法如果哪里不对欢迎指出&#xff0c;主页https://blog.csdn.net/qq_57785602?typeblogscp 可以在win系统使用&#xff0c;本文百分之八十写的是win系统怎么使用&#xff0c;在本地上到服务器文件,从服务器下载文件到本地用工具连接到公司服务器时&#xff…...

数据质量怎么监控

目录 一、任务基线级别 二、任务级别 & 表级别 三、字段级别 1. 对指标字段的监控 2. 对维度字段的监控 四、报表级别监控 五、总结 跑了几场面试&#xff0c;数据质量怎么监控是经常被问到的问题&#xff0c;仅次于自我介绍。 因为数据行业发展了几年&#xff0c;数…...

.NET Core 实现Excel的导入导出

.NET Core 使用NPOI实现Excel的导入导出前言NPOI简介一、安装相对应的程序包1.1、在 “管理NuGet程序包” 中的浏览搜索&#xff1a;“NPOI”二、新建Excel帮助类三、调用3.1、增加一个“keywords”模型类&#xff0c;用作导出3.2、添加一个控制器3.3、编写导入导出的控制器代码…...

排好队,一个一个来:宫本武藏教你学队列(附各种队列源码)

文章目录前言&#xff1a;理解“队列”的正确姿势一个关于队列的小思考——请求处理队列的两大“护法”————顺序队列和链式队列数组实现的队列链表实现的队列循环队列关于开篇&#xff0c;你明白了吗&#xff1f;最后说一句前言&#xff1a; 哈喽&#xff01;欢迎来到黑洞晓…...

C语言--动态内存管理1

目录前言动态内存函数介绍mallocfreecallocrealloc常见的动态内存错误对NULL指针的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放一块动态开辟内存的一部分对同一块动态内存多次释放动态开辟内存忘记释放&#xff08;内存泄漏&#xff09;对通讯…...

HTTPS 的工作原理

1、客户端发起 HTTPS 请求 这个没什么好说的&#xff0c;就是用户在浏览器里输入一个 https 网址&#xff0c;然后连接到 server 的 443 端口。 2、服务端的配置 采用 HTTPS 协议的服务器必须要有一套数字证书&#xff0c;可以自己制作&#xff0c;也可以向组织申请&#xf…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手

华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...