如何在 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 个简单步骤:
在 create() 钩子 里,创建 防抖回调,并将其赋值到实例上:this.debouncedWatch = debounce(..., 500)。
在 观察者 回调 watch.value() { ... } 中 传入正确的参数 调用 this.debouncedWatch()。
最后,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 个步骤:
. 在 create() 钩子 里,创建实例后,立刻将 防抖回调 debounce(event => {...}, 500) 赋值到 this.debouncedHandler 。
在输入框的 template 中 给 v-on:input 赋上 debouncedHandler :<input v-on:input="debouncedHandler" type="text" />
最后,在卸载组件之前, 在 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 中使用 防抖 和 节流
大厂面试题分享 面试题库前后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库 https://mp.weixin.qq.com/s?__bizMzU5NzA0NzQyNg&mid2247485824&idx3&sn70cd26a7c0c683de64802f6cb9835003&scene21#wech…...
美国Linux服务器系统增强安全的配置
美国Linux服务器系统可能出现的安全漏洞中,更多是由于不当的系统配置所造成的,用户们可以通过一些适当的安全配置来防止问题的发生。美国Linux服务器系统上运行的服务越多,不当配置的概率也就越高,那么系统出现安全问题的可能性也…...
【史上最全面esp32教程】oled显示篇
文章目录前言介绍及库下载基础使用引脚的连接使用函数总结前言 本节课主要讲的是OLED的基础使用。使用的oled为0.96寸,128*64。 大家的其他型号也是可以用的。 提示:以下是本篇文章正文内容,下面案例可供参考 介绍及库下载 oled的简介&…...
第十四届蓝桥杯三月真题刷题训练——第 21 天
目录 第 1 题:灭鼠先锋 问题描述 运行限制 代码: 思路: 第 2 题:小蓝与钥匙 问题描述 答案提交 运行限制 代码: 思路 : 第 3 题:李白打酒加强版 第 4 题:机房 第 1 题࿱…...
css绘制一个Pinia小菠萝
效果如下: pinia小菠萝分为头部和身体,头部三片叶子,菠萝为身体 头部 先绘制头部的盒子,将三片叶子至于头部盒子中 先绘制中间的叶子,利用border-radius实现叶子的效果,可以借助工具来快速实现圆角的预想…...
OpenCV入门(二十)快速学会OpenCV 19 对象测量
OpenCV入门(二十)快速学会OpenCV 19 对象测量1.对象测量2.多边形拟合3.计算对象中心作者:Xiou 1.对象测量 opencv 中对象测量包括: 如面积,周长,质心,边界框等。 弧长与面积测量; …...
TCP和UDP协议的区别?
是否面向连接: TCP 是面向连接的传输,UDP 是面向无连接的传输。 是否是可靠传输:TCP是可靠的传输服务,在传递数据之前,会有三次握手来建立连接;在数据传递时,有确认、窗口、重传、拥塞控制机制…...
【C语言蓝桥杯每日一题】——排序
【C语言蓝桥杯每日一题】—— 排序😎前言🙌排序🙌总结撒花💞😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介&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:共享进程空间8.2、案例2:更改启动命令、容器镜像8.3、案例3:调试节点8.4、其他一、describe 显示某个资源或某组资…...
AJAX,Axios,JSON简单了解
一. AJAX简介概念: AJAX(Asynchronous JavaScript And XML): 异步的JavaScript 和XMLAJAX作用:1.与服务器进行数据交换: 通过AJAX可以给服务器发送请求,并获取服务器响应的数据使用了AJAX和服务器进行通信,就可以使用 HTMLAJAX来替换JSP页面了2.异步交互…...
私域流量该如何打造?这套模式直接借鉴
梦龙商业案例分析,带你了解商业背后的秘密 古往今来,消费方与购买方的地位似乎就没有变过,消费者始终是处在被动接受的地位。 但到了现在,其实消费地位早已经不知不觉产生了改变。 就比如以前都是厂家有什么消费者买什么&#…...
【jenkins部署】一文弄懂自动打包部署(前后台)
这里写目录标题序言软件安装jdkmaven配置maven阿里镜像以及本地库位置git安装安装jenkins插件安装环境配置创建项目配置gitee生成gitee WebHookmaven打包验证是否打包成功连接远程服务器并重启服务远程服务器生成私钥配置ssh项目配置ssh脚本vue项目打包nodejs安装下载配置环境变…...
应届生投腾讯,被面试官问了8个和 ThreadLocal 相关的问题。
问:谈一谈ThreadLocal的结构。 ThreadLocal内部维护了一个ThreadLocalMap静态内部类,ThreadLocalMap中又维护了一个Entry静态内部类,和Entry数组。 Entry类继承弱引用类WeakReference,Entry类有一个有参构造函数,参数…...
Linux命令scp用法
本文主要讲的是scp用法如果哪里不对欢迎指出,主页https://blog.csdn.net/qq_57785602?typeblogscp 可以在win系统使用,本文百分之八十写的是win系统怎么使用,在本地上到服务器文件,从服务器下载文件到本地用工具连接到公司服务器时ÿ…...
数据质量怎么监控
目录 一、任务基线级别 二、任务级别 & 表级别 三、字段级别 1. 对指标字段的监控 2. 对维度字段的监控 四、报表级别监控 五、总结 跑了几场面试,数据质量怎么监控是经常被问到的问题,仅次于自我介绍。 因为数据行业发展了几年,数…...
.NET Core 实现Excel的导入导出
.NET Core 使用NPOI实现Excel的导入导出前言NPOI简介一、安装相对应的程序包1.1、在 “管理NuGet程序包” 中的浏览搜索:“NPOI”二、新建Excel帮助类三、调用3.1、增加一个“keywords”模型类,用作导出3.2、添加一个控制器3.3、编写导入导出的控制器代码…...
排好队,一个一个来:宫本武藏教你学队列(附各种队列源码)
文章目录前言:理解“队列”的正确姿势一个关于队列的小思考——请求处理队列的两大“护法”————顺序队列和链式队列数组实现的队列链表实现的队列循环队列关于开篇,你明白了吗?最后说一句前言: 哈喽!欢迎来到黑洞晓…...
C语言--动态内存管理1
目录前言动态内存函数介绍mallocfreecallocrealloc常见的动态内存错误对NULL指针的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放一块动态开辟内存的一部分对同一块动态内存多次释放动态开辟内存忘记释放(内存泄漏)对通讯…...
HTTPS 的工作原理
1、客户端发起 HTTPS 请求 这个没什么好说的,就是用户在浏览器里输入一个 https 网址,然后连接到 server 的 443 端口。 2、服务端的配置 采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
