Vue 3 中的极致防抖/节流(含常见方式防抖/节流)

news2025/1/15 22:34:59

请添加图片描述

各位朋友你们好呀。今天是立春,明天就是正月十五元宵节了,这种立春 + 元宵相隔的时候,可是很难遇到的,百年中就只有几次。在这提前祝大家元宵快乐。

今天给大家带来的是Vue 3 中的极致防抖/节流(含常见方式防抖/节流)这篇文章,文章中不仅会讲述原来使用的防抖或节流方式,还会带来新的一种封装方式,使用起来更简单、更清晰。

前言

在前端的开发过程中,在涉及到与用户交互的过程中是基本上都是需要处理的,常规操作就是在对应位置加上防抖或者节流。

加上防抖或者节流的作用:一是为了防止用户频繁操作;二是为了节约一定的服务器资源,减少资源浪费的情况。

防抖或节流原理

防抖(debounce)

如果用户多次频繁操作以最后一次为准,当然也可以以第一次为准,进行数据更新或者网络资源请求,以消除冗余的操作,或者减少一定的请求资源浪费。

示例代码

function debounce (fn, delay = 300){
    let timer = null
    return function (...args) {
        clearTimeout(timer)
        timer = setTimeout(()=>{
            fn.call(this, ...args)
        }, delay);
    }
}

使用

debounce(()=> count += 1, 1000)

节流(throttle )

在一定时间范围内,用户触发多次只会执行一次以达到防止用户频繁操作的目的。

示例代码

let timer = null
function throttle (fn, delay = 300) {
    if(timer == null){
        timer = setTimeout(() => {
            fn()

            clearTimeout(timer)
            timer = null
        }, delay);
    }
}

使用

throttle(()=> count += 1, 1000)

环境说明

  • vue 3
  • vite

新封装

这里我分两个模块来讲述。一个是防抖;另一个是节流。

虽然这两个差别不是很大,但还是有区别的。上车,兄弟们。🚗🚗🚗

防抖(debounce)

先看常见封装内容。

常见封装-1

代码

function debounce (fn, delay = 300){
    let timer = null
    return function (...args) {
        if(timer != null){
            clearTimeout(timer)
            timer = null
        }
        timer = setTimeout(()=>{
            fn.call(this, ...args)
        }, delay);
    }
}

使用

const addCount = debounce(()=> count.value += 1, 1000)

常见封装-2

代码

let timer = null
function debounce (fn, delay = 1000){
    if(timer != null){
        clearTimeout(timer)
        timer = null
    }
    timer = setTimeout(fn, delay)
}

使用

const addCount = () => debounce(()=> count.value += 1, 1000)

新封装

这里我们需要借助 vue 3 中的 customRef 来实现我们的新方式。这里我就不具体写了。我直接在每行代码上面添加注释。我相信朋友你是能看懂的。🌹🌹🌹

代码

// 从 vue 中引入 customRef 和 ref
import { customRef, ref } from "vue"

// data 为创建时的数据
// delay 为防抖时间
function debounceRef (data, delay = 300){
    // 创建定时器
    let timer = null;
    // 对 delay 进行判断,如果传递的是 null 则不需要使用 防抖方案,直接返回使用 ref 创建的。
    return delay == null 
        ? 
        // 返回 ref 创建的
        ref(data)
        : 
        // customRef 中会返回两个函数参数。一个是:track 在获取数据时收集依赖的;一个是:trigger 在修改数据时进行通知派发更新的。
        customRef((track, trigger) => {
            return {
                get () {
                    // 收集依赖
                    track()
                    // 返回当前数据的值
                    return data
                },
                set (value) {
                    // 清除定时器
                    if(timer != null){
                        clearTimeout(timer)
                        timer = null
                    }
                    // 创建定时器
                    timer = setTimeout(() => {
                        // 修改数据
                        data = value;
                        // 派发更新
                        trigger()
                    }, delay)
                }
            }
        })
}

使用

// 创建
const count = debounceRef(0, 300)

// 函数中使用
const addCount = () => {
  count.value += 1
}

// v-model 中使用
<input type="text" v-model="count">

节流(throttle)

我们还是一样,先看常见封装内容。

常见封装-1

代码

let timer = null
function throttle (fn, delay = 300) {
    if(timer == null){
        timer = setTimeout(() => {
            fn()

            clearTimeout(timer)
            timer = null
        }, delay);
    }
}

使用

const addCount = () => throttle(()=> count.value += 1, 1000)

常见封装-2

代码

function throttle (fn, delay = 300) {
    let timer = null
    return function (...args) {
        if(timer == null){
            timer = setTimeout(() => {
                fn.call(this, ...args)
    
                clearTimeout(timer)
                timer = null
            }, delay);
        }
    }
}

使用

const addCount = throttle(()=> count.value += 1, 1000)

新封装

节流和防抖在封装和使用上大同小异的。

代码

// data 为创建时的数据
// delay 为节流时间
function throttleRef (data, delay = 300){
    // 创建定时器
    let timer = null;
    // 对 delay 进行判断,如果传递的是 null 则不需要使用 节流方案,直接返回使用 ref 创建的。
    return delay == null 
        ? 
        // 返回 ref 创建的
        ref(data)
        : 
        // customRef 中会返回两个函数参数。一个是:track 在获取数据时收集依赖的;一个是:trigger 在修改数据时进行通知派发更新的。
        customRef((track, trigger) => {
            return {
                get () {
                    // 收集依赖
                    track()
                    // 返回当前数据的值
                    return data
                },
                set (value) {
                    // 判断
                    if(timer == null){
                        // 创建定时器
                        timer = setTimeout(() => {
                            // 修改数据
                            data = value;
                            // 派发更新
                            trigger()
                            // 清除定时器
                            clearTimeout(timer)
                            timer = null
                        }, delay)
                    }
                }
            }
        })
}

使用

// 创建
const count = debounceRef(0, 300)

// 函数中使用
const addCount = () => {
  count.value += 1
}

// v-model 中使用
<input type="text" v-model="count">

总结

以上便是Vue 3 中的极致防抖/节流(含常见方式防抖/节流)这篇文章的全部内容,如有不足或朋友你有更好的方式或者其他独到的见解,欢迎评论 + 私信。

当然朋友你又学到了一招可以点赞 + 关注 + 评论哦。

希望本篇文章对正在阅读的朋友你有所帮助。

想了解vue 2中如何实现相同方案的朋友可以点击这里 👉 Vue 2 中的实现 CustomRef 方式防抖/节流

我是桃小瑞,公众号 @ 桃小瑞。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/273633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT给程序员人手一个,这很朋克

目录ChatGPT、程序员、朋克为什么程序员需要ChatGPT&#xff0c;为什么这很朋克总结ChatGPT、程序员、朋克 本文由ChatGPT编写。 ChatGPT是由OpenAI开发的大型语言模型。它的核心功能是生成人类语言文本&#xff0c;因此有多种应用场景&#xff0c;如文本生成、对话生成、文本…

「VUE架构」Vue2与Vue3的区别

文章目录前言一、性能比Vue2快1.2~2倍1.1 diff算法优化1.2 事件侦听缓存1.3 减少创建组件实例的开销二、 按需编译&#xff0c;体积比Vue2更小三、 Compostion API四、 支持TS五、 自定义渲染API六、更先进的组件七、 更快的开发体验前言 VUE是一套用于构建用户界面的渐进式框…

Nginx常用功能举例解析

Nginx提供的基本功能服务从大体上归纳为"基本HTTP服务"、“高级HTTP服务”和"邮件服务"等三大类。基本HTTP服务Nginx可以提供基本HTTP服务&#xff0c;可以作为HTTP代理服务器和反向代理服务器&#xff0c;支持通过缓存加速访问&#xff0c;可以完成简单的…

【FPGA】Verilog:组合逻辑电路应用 | 数码管 | 8421BCD编码 | 转换七段数码管段码

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;数码管的使用 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器&#xff1a;2M…

Vue-VueRouter

前言 Vue Router 是 Vue.js (opens new window)官方的路由管理器。它和 Vue.js 的核心深度集成&#xff0c;让构建单页面应用变得易如反掌。包含的功能有&#xff1a; 嵌套的路由/视图表模块化的、基于组件的路由配置路由参数、查询、通配符基于 Vue.js 过渡系统的视图过渡效果…

SPSS聚类分析(含k-均值聚类,系统聚类和二阶聚类)

本篇博客主要是根据1、聚类的基本知识点_哔哩哔哩_bilibili系列视频进行的学习记录一、SPSS聚类分析的基本知识点1、什么是聚类分析?聚类分析(Cluster analysis)又叫做群集分析,通过一些属性将对象或变量分成不同的组别&#xff0c;在同一类下的对象或变量在这些属性上具有一些…

最全面的SpringBoot教程(四)——数据库连接

前言 本文为 最全面的SpringBoot教程&#xff08;四&#xff09;——数据库连接 相关知识&#xff0c;下边将对JDBC连接配置&#xff0c;与使用Druid数据源&#xff0c;从添加依赖到修改配置项再到测试进行详尽介绍~ &#x1f4cc;博主主页&#xff1a;小新要变强 的主页 &…

C语言深度解剖-关键字(5)

目录 if else 组合 if else 的基本用法 注释 深入理解bool float(double)与浮点数的比较 写在最后&#xff1a; if else 组合 if else 的基本用法 #include <stdio.h>int main() {int flag 1;if (flag 1){printf("flag %d\n", flag);}else if (flag…

crmeb pro多门店版二次开发

重启一下swool 新创建的数据库表 ALTER TABLE eb_store_cart ADD price DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT 单独改价 AFTER status;ALTER TABLE eb_store_order ADD car_no VARCHAR(255) NOT NULL DEFAULT COMMENT 车牌号 AFTER erp_order_id, ADD frame_no VARCHA…

2023软考系统集成项目管理工程师易混淆知识点~(7)

将2023上半年软考《系统集成项目管理工程师》易混淆知识点&#xff0c;分享给大家&#xff0c;快来跟着一起打卡学习吧&#xff01;概念辨析 1:项目、运营概念:(1)项目:项目是为达到特定目的&#xff0c;使用一定资源&#xff0c;在确定的期间内&#xff0c;为特定发起人而提供…

Linux perf的使用(一)

文章目录前言一、perf简介二、perf子命令简介三、perf工作模式3.1 计数3.2 采样参考资料前言 系统级性能优化通常包括两个阶段&#xff1a;性能剖析&#xff08;performance profiling&#xff09;和代码优化。 &#xff08;1&#xff09;性能剖析的目标是寻找性能瓶颈&#x…

python(13)--字典(Dict)

一、字典的基本操作 1.定义字典 字典也是一个列表型的数据结构&#xff0c;字典的数据是用“{ }”装的&#xff08;列表&#xff1a;[ ]&#xff0c;元组&#xff1a;( )&#xff09;&#xff0c;字典的元素是一一对应的关系“key-value”。 格式&#xff1a; Dictname{ key1…

vue中父子组件的传值

1. 父组件给子组件传值 主要两个步骤&#xff1a; 1. 在父组件调用子组件的时候绑定数据 2. 在子组件里面通过props接收父组件传过来的数据 2. 子组件给父组件传值 主要三个步骤&#xff1a; 1.在子组件中创建一个按钮&#xff0c;给按钮绑定一个点击事件 2.在响应该点击事件…

NSSRound#7

[NSSRound#7 Team]ec_RCE 源码: <?PHPif(!isset($_POST["action"]) && !isset($_POST["data"]))show_source(__FILE__);putenv(LANGzh_TW.utf8); $action $_POST["action"];$data "".$_POST["data"]."…

Java综合实验1题目: 猜心术---猜姓氏游戏

一、 实验内容及要求 假设游戏者共有十人&#xff0c;且有10个不同的姓&#xff1a;张、王、李、赵、刘、于、许、金、钱、孙&#xff0c;魔术师将十个姓写在四张纸牌上&#xff0c;游戏者只需指出那几张纸上有自己的姓&#xff0c;魔术师就能准确的说出游戏者的姓&#xff0c…

ChatGPT 为我制作了一张地图

有人说&#xff1a;一个人从1岁活到80岁很平凡&#xff0c;但如果从80岁倒着活&#xff0c;那么一半以上的人都可能不凡。 生活没有捷径&#xff0c;我们踩过的坑都成为了生活的经验&#xff0c;这些经验越早知道&#xff0c;你要走的弯路就会越少。 今天在刷视频的时候看到了…

Java 并发在项目中的使用场景

1、并发编程的三个核心问题&#xff1a;&#xff08;1&#xff09;分工&#xff1a;所谓分工指的是如何高效地拆解任务并分配给线程&#xff08;2&#xff09;同步&#xff1a;而同步指的是线程之间如何协作&#xff08;3&#xff09;互斥&#xff1a;互斥则是保证同一时刻只允…

本科大数据专业能找到大数据开发的工作么

本科大数据专业能不能找到大数据开发的工作取决于你在校期间大数据学科学习的怎么样~ 目前大二就还有时间去学习&#xff0c;趁着空余时间找个完整的学习路线去学习&#xff0c;争取能够在校招的时候就找到心仪的工作技术过关的话是完全没有问题的&#xff0c;而且加上你还有兴…

PythonWeb开发基础(三)类Flask框架请求封装

课程地址&#xff1a;Python 工程师进阶技术图谱 文章目录类Flask框架请求封装HTTP请求解析的python实现1、解析查询字符串2、多值问题使用webob库解析请求Bug记录bug&#xff1a;AttributeError: module cgi has no attribute parse_qs类Flask框架请求封装 Web服务器 本质是…

【C++提高编程】list 容器详解(附测试用例与结果图)

目录1. list容器1.1 list基本概念1.2 list构造函数&#xff08;初始化&#xff09;1.3 list 赋值和交换1.4 list 大小操作1.5 list 插入和删除1.6 list 数据存取1.7 list 反转&#xff08;reverse&#xff09;、排序&#xff08;sort&#xff09;和去重&#xff08;unique&…