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

Vue中nextTick的使用及原理

在Vue.js中,nextTick方法可以让我们在DOM更新后执行一些操作。通常情况下,在数据发生变化后,Vue.js会异步地更新DOM,这样可以减少不必要的DOM操作,提高性能。但是,有时候我们需要在DOM更新后对页面进行一些后续操作,比如修改元素的样式、设置定时器等,这时候就需要用到nextTick方法。

一、nextTick的使用场景

1. 访问更新后的DOM

在一些特殊的场景中,我们可能需要访问更新后的DOM,比如在通过ref访问组件或子元素时,由于DOM更新是异步的,所以需要使用nextTick方法来确保能够访问到更新后的DOM。

<template><div><p ref="msg">Hello, World!</p></div>
</template><script>
export default {mounted() {// 此时访问DOM元素是无法获取到更新后的text值,需要使用nextTick方法console.log(this.$refs.msg.innerText); // 输出:Hello, World!this.$nextTick(() => {console.log(this.$refs.msg.innerText); // 输出:Hello, Vue!});},methods: {updateMessage() {this.$refs.msg.innerText = 'Hello, Vue!';}}
}
</script>

在上述代码中,当mounted钩子函数被调用时,this.$refs.msg是无法获取到更新后的text值,需要使用nextTick方法来确保能够访问到更新后的DOM。

2. 在更新后执行某些操作

有时候,我们需要在DOM更新后执行某些操作,比如在动态修改元素的样式、设置定时器等。这种情况下,同样也需要使用nextTick方法。

<template><div><button @click="changeColor">Change Color</button><p :style="{ color: textColor }">Hello, World!</p></div>
</template><script>
export default {data() {return {textColor: 'black'}},methods: {changeColor() {// 使用nextTick确保视图已经更新完成this.$nextTick(() => {this.textColor = 'red';});}}
}
</script>

在上述代码中,当用户点击按钮时,我们需要动态地将文本颜色修改为红色。由于DOM更新是异步的,如果直接在点击事件处理函数中修改文本颜色可能无法生效。因此,我们需要使用nextTick方法确保DOM更新完成后再进行修改。

二、nextTick的原理

在Vue.js中,nextTick方法的实现原理主要基于两个核心技术:Promise和microtask。

Promise

Promise是ES6引入的一个新特性,它可以异步地执行JavaScript代码并返回异步操作的结果。Promise使用起来非常简单,我们只需要调用其构造函数即可创建一个Promise实例。

const promise = new Promise((resolve, reject) => {// 异步执行的代码setTimeout(() => {resolve('success');}, 1000);
});promise.then(result => {console.log(result);
}).catch(error => {console.log(error);
});

在上述代码中,我们通过Promise构造函数创建了一个异步操作,它会在1秒后返回一个成功的结果’success’。然后,我们使用then方法来处理异步操作返回的结果。

microtask

microtask是JavaScript引擎中的一个任务队列,它用于存储一些需要异步执行的任务。当主线程执行完成后,会立即执行microtask队列中的所有任务,然后再执行下一轮的渲染更新。

在Vue.js中,nextTick方法就是利用了Promise和microtask技术来实现的。当我们调用nextTick方法时,Vue.js会将回调函数添加到一个microtask队列中,在DOM更新完成后立即执行这个回调函数。

Vue.prototype.$nextTick = function (fn: Function) {const _this = this;if (pending) {callbacks.push(() => {fn.call(_this);});} else {pending = true;timerFunc(() => {const ctx = _this ? _this.$options.context : null;fn.call(ctx);flushCallbacks();});}
};

在Vue.js的源码中,我们可以看到nextTick方法的实现逻辑:如果已经有回调函数在等待执行,会将新的回调函数加入到队列中;否则,会调用timerFunc函数异步地将回调函数添加到microtask队列中,然后在DOM更新后立即执行。

const callbacks = [];
let pending = false;function flushCallbacks() {pending = false;const copies = callbacks.slice(0);callbacks.length = 0;for (let i = 0; i < copies.length; i++) {copies[i]();}
}let timerFunc;if (typeof Promise !== 'undefined' && isNative(Promise)) {timerFunc = () => {Promise.resolve().then(flushCallbacks)};
} else if (!isIE && typeof MutationObserver !== 'undefined' && (isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]')) {let counter = 1;const observer = new MutationObserver(flushCallbacks);const textNode = document.createTextNode(String(counter));observer.observe(textNode, {characterData: true});timerFunc = () => {counter = (counter + 1) % 2;textNode.data = String(counter);};
} else {timerFunc = () => {setTimeout(flushCallbacks, 0);};
}

在上述代码中,timerFunc函数是nextTick方法的关键。它会根据当前浏览器环境的支持情况,选择不同的异步执行方式。如果浏览器支持Promise对象,则使用Promise.resolve().then(flushCallbacks)来添加microtask任务;如果浏览器不支持Promise对象但支持MutationObserver,则使用MutationObserver,在文本节点变化时执行回调函数;否则,使用setTimeout来异步地执行回调函数。

综合以上讨论,我们可以得出nextTick的执行流程:

  1. 将回调函数加入到callbacks队列中;
  2. 如果没有正在等待执行的回调函数,使用timerFunc异步地将回调函数添加到microtask队列中;
  3. 在DOM更新后立即执行microtask队列中的所有回调函数。

三、小结

本文主要介绍了Vue.js中nextTick方法的使用场景和原理。nextTick方法可以让我们在DOM更新后执行一些操作,它的原理基于Promise和microtask技术。当调用nextTick方法时,Vue.js会将回调函数添加到一个microtask队列中,在DOM更新完成后立即执行这个回调函数。需要注意的是,在使用nextTick方法时,要确保回调函数不会频繁地触发DOM更新,否则可能会影响性能。

完整项目附件:点此下载

相关文章:

Vue中nextTick的使用及原理

在Vue.js中&#xff0c;nextTick方法可以让我们在DOM更新后执行一些操作。通常情况下&#xff0c;在数据发生变化后&#xff0c;Vue.js会异步地更新DOM&#xff0c;这样可以减少不必要的DOM操作&#xff0c;提高性能。但是&#xff0c;有时候我们需要在DOM更新后对页面进行一些…...

【Linux】拓展:运维面试题,进程管理常见的7大问题

目录 一、如何判断一个程序是单线程还是多线程 二、僵尸进程是什么&#xff0c;有什么危害&#xff0c;如何解决 三、如何找回删掉的文件 四、删除文件以后&#xff0c;空间不释放 五、遇到一个病毒&#xff08;如死循环病毒&#xff09;&#xff0c;解决思路 六、机器开机…...

Android修行手册 - 一文全了解Kotlin几种静态变量、函数实现的那些事

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…...

Qt QTableView排序

1.简介 在开发过程中&#xff0c;我们需要通过点击表头来对QTableView或QTreeView等一系列高级视图进行排序操作&#xff0c;以下是进行排序的步骤。 步骤&#xff1a; 首先创建了一个QStandardItemModel对象或者继承QAbstractTableModel类作为数据模型&#xff0c;并设置了…...

Linux shell编程学习笔记22: () $() (()) 的用法小结

最近学习Linux Shell编程&#xff0c;对 () (()) [] [[]]等符号的用法还是有点分不太清楚&#xff0c;于是决定再梳理一下。今天先整理 () $() (()) 的用法。 1 单小括号() 1.1 子shell&#xff08;命令组&#xff09; 括号中的命令将会新开一个子shell顺序执行&#xff0c;所…...

1. Pthreads专栏简介

在基于共享内存的多处理器架构中&#xff0c;可使用线程实现并行。以前硬件供应商一般都会提供相应硬件专用的线程库&#xff0c;使得代码的可移植性成为另开发者头疼的一个问题。在UNIX系统中&#xff0c;IEEE POSIX 1003.1c标准已经定义了基于C的标准化线程编程接口规范&…...

C++17 fallthrough属性

在C17中&#xff0c;引入了[[fallthrough]]属性。这个属性主要用于switch语句中&#xff0c;用于告诉编译器&#xff0c;从上一个case标签到下一个case标签的执行是有意为之的&#xff0c;不应该被诊断为错误。 在switch-case语句中&#xff0c;如果当前case分支中不加break&a…...

STM32 蜂鸣器介绍 配置 播放音节

蜂鸣器一般被分为两类&#xff1a;有源蜂鸣器和无源蜂鸣器。其中源是振荡源。有源蜂鸣器内部有正当电路&#xff0c;可以把直流电源转换为一定频率的脉冲信号。因为它一直输出一定的频率&#xff0c;我们无法改变频率&#xff0c;我们只能通过电源&#xff0c;控制它发不发声&a…...

多目标最优化的资产配置

摘要及声明 1&#xff1a;本文主要对基于均值方差最优化的资产配置方法进行拓展&#xff0c;从多目标最优化的角度看待资产配置并可视化展示&#xff1b; 2&#xff1a;本文主要为理念的讲解&#xff0c;模型也是笔者自建&#xff0c;文中假设与观点是基于笔者对模型及数据的…...

word图片的标题跑到了图片的上方。

问题描述&#xff1a;在写论文时&#xff0c;在word文档中插入了一个svg图片&#xff0c;然后在图片下方输入标题。后面可能是调整了svg图片的大小&#xff0c;标题跑到了图片的上方。 具体情况如下图所示。标题明显跑到了图片的上方。 解决办法&#xff1a;把svg图片格式调成…...

electron打包下载资源失败,设置国内镜像

0.electron介绍 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows、Linux及macOS上运行的跨平台应用。可以用原生html写&#xff0c;也可以用vue等…...

架构漫谈 - 如何设计高性能、高可用、高扩展架构

文章目录 一、如何设计高扩展架构架构设计复杂度模型可扩展复杂度模型"拆分"复杂度分析和设计"封装"复杂度分析和设计(1)规则引擎:美团MazeGO规则引擎(2)微内核:OSGI微内核(3)抽象层:Linux VFS抽象层(4)设计模式二、设计高性能架构单机高性能集…...

matlab 读写ENVI标准数据

本博客主要讲解如何读、生成ENVI标准格式的数据。主要分为四部分&#xff1a;读取ENVI头文件、读取ENVI数据、写入ENVI头文件、生成ENVI标准数据&#xff0c;最后附加讲解了本人写的生成hdr文本文件代码。此外&#xff0c;文中还具体介绍写代码的一些思路。 一、读取ENVI头文件…...

如何对ppt文件设置修改权限?

PPT文件会应用在会议、演讲、课件等工作生活中&#xff0c;当我们制作好了PPT之后&#xff0c;保护内容防止在演示时出错是很重要的&#xff0c;那么如何将PPT文件设置成禁止修改模式呢&#xff1f;今天分享几个方法给大家。 方法一 将PPT文件直接保存或者另存为一份文件&…...

STM32G030F6P6 芯片实验 (二)

STM32G030F6P6 芯片实验 (二) Hello World - GPIO LED 尝试了下, 从 0 开始建 MDK HAL M0plus Project, 成功点亮 LED了。 但是 ST-LINK跑着跑着, 码飞了! 不知飞哪去了。 只好拿 MX 建了个 MDK Base。 呼叫 SysTick HAL_Delay(), 切换 LED。 基本上都是一样的用法, 只是换…...

时间序列预测模型实战案例(七)(TPA-LSTM)结合TPA注意力机制的LSTM实现多元预测

论文地址->TPA-LSTM论文地址 项目地址-> TPA-LSTM时间序列预测实战案例 本文介绍 本文通过实战案例讲解TPA-LSTM实现多元时间序列预测&#xff0c;在本文中所提到的TPA和LSTM分别是注意力机制和深度学习模型,通过将其结合到一起实现时间序列的预测&#xff0c;本文利用…...

Mysql多表设计

前言 多表查询中要给每一表起别名 tableA as 别名1 , tableB as 别名2 ; &#xff08;111111推荐&#xff09; tableA 别名1 , tableB 别名2 ; 例子&#xff1a; select emp.name , dept.name from tb_emp emp inner join tb_dept dept on emp.dept_id dept.id; 一对一 在任…...

第九章:最新版零基础学习 PYTHON 教程—Python 元组(第五节 -清除元组的5种方式方法)

有时,在处理记录数据时,我们可能会遇到需要执行数据记录清除的问题。元组是不可变的,无法修改,因此使这项工作变得困难。让我们讨论执行此任务的某些方法。 目录 方法 #1:使用 list() + clear() + tuple() 方法#2:使用 tuple() 重新初始化...

学习笔记4——JVM运行时数据区梳理

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/192489.html 类装载器classLoader&#xff1a; 将本地的字节码文件.class 加载到内存方法区中成为元数据模板&#xff08;两个class对象是否为同一个类要求&#xff1a;完整…...

Splunk 创建特色 dashboard 报表

1: 背景: 对原有的dashboard 进行增加点东西,特别是文字部分: 比如: 增加:“this is a guidline for how to use performance". 这段话,就不能写在title, 那样,这段文字,会出现在dashboard 的PDF 文件的分割线的上面,不符合要求。 2: 解决问题: 正确的做法是…...

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

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

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...