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的执行流程:
- 将回调函数加入到callbacks队列中;
- 如果没有正在等待执行的回调函数,使用timerFunc异步地将回调函数添加到microtask队列中;
- 在DOM更新后立即执行microtask队列中的所有回调函数。
三、小结
本文主要介绍了Vue.js中nextTick方法的使用场景和原理。nextTick方法可以让我们在DOM更新后执行一些操作,它的原理基于Promise和microtask技术。当调用nextTick方法时,Vue.js会将回调函数添加到一个microtask队列中,在DOM更新完成后立即执行这个回调函数。需要注意的是,在使用nextTick方法时,要确保回调函数不会频繁地触发DOM更新,否则可能会影响性能。
完整项目附件:点此下载
相关文章:
Vue中nextTick的使用及原理
在Vue.js中,nextTick方法可以让我们在DOM更新后执行一些操作。通常情况下,在数据发生变化后,Vue.js会异步地更新DOM,这样可以减少不必要的DOM操作,提高性能。但是,有时候我们需要在DOM更新后对页面进行一些…...
【Linux】拓展:运维面试题,进程管理常见的7大问题
目录 一、如何判断一个程序是单线程还是多线程 二、僵尸进程是什么,有什么危害,如何解决 三、如何找回删掉的文件 四、删除文件以后,空间不释放 五、遇到一个病毒(如死循环病毒),解决思路 六、机器开机…...
Android修行手册 - 一文全了解Kotlin几种静态变量、函数实现的那些事
点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&…...
Qt QTableView排序
1.简介 在开发过程中,我们需要通过点击表头来对QTableView或QTreeView等一系列高级视图进行排序操作,以下是进行排序的步骤。 步骤: 首先创建了一个QStandardItemModel对象或者继承QAbstractTableModel类作为数据模型,并设置了…...
Linux shell编程学习笔记22: () $() (()) 的用法小结
最近学习Linux Shell编程,对 () (()) [] [[]]等符号的用法还是有点分不太清楚,于是决定再梳理一下。今天先整理 () $() (()) 的用法。 1 单小括号() 1.1 子shell(命令组) 括号中的命令将会新开一个子shell顺序执行,所…...
1. Pthreads专栏简介
在基于共享内存的多处理器架构中,可使用线程实现并行。以前硬件供应商一般都会提供相应硬件专用的线程库,使得代码的可移植性成为另开发者头疼的一个问题。在UNIX系统中,IEEE POSIX 1003.1c标准已经定义了基于C的标准化线程编程接口规范&…...
C++17 fallthrough属性
在C17中,引入了[[fallthrough]]属性。这个属性主要用于switch语句中,用于告诉编译器,从上一个case标签到下一个case标签的执行是有意为之的,不应该被诊断为错误。 在switch-case语句中,如果当前case分支中不加break&a…...
STM32 蜂鸣器介绍 配置 播放音节
蜂鸣器一般被分为两类:有源蜂鸣器和无源蜂鸣器。其中源是振荡源。有源蜂鸣器内部有正当电路,可以把直流电源转换为一定频率的脉冲信号。因为它一直输出一定的频率,我们无法改变频率,我们只能通过电源,控制它发不发声&a…...
多目标最优化的资产配置
摘要及声明 1:本文主要对基于均值方差最优化的资产配置方法进行拓展,从多目标最优化的角度看待资产配置并可视化展示; 2:本文主要为理念的讲解,模型也是笔者自建,文中假设与观点是基于笔者对模型及数据的…...
word图片的标题跑到了图片的上方。
问题描述:在写论文时,在word文档中插入了一个svg图片,然后在图片下方输入标题。后面可能是调整了svg图片的大小,标题跑到了图片的上方。 具体情况如下图所示。标题明显跑到了图片的上方。 解决办法:把svg图片格式调成…...
electron打包下载资源失败,设置国内镜像
0.electron介绍 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows、Linux及macOS上运行的跨平台应用。可以用原生html写,也可以用vue等…...
架构漫谈 - 如何设计高性能、高可用、高扩展架构
文章目录 一、如何设计高扩展架构架构设计复杂度模型可扩展复杂度模型"拆分"复杂度分析和设计"封装"复杂度分析和设计(1)规则引擎:美团MazeGO规则引擎(2)微内核:OSGI微内核(3)抽象层:Linux VFS抽象层(4)设计模式二、设计高性能架构单机高性能集…...
matlab 读写ENVI标准数据
本博客主要讲解如何读、生成ENVI标准格式的数据。主要分为四部分:读取ENVI头文件、读取ENVI数据、写入ENVI头文件、生成ENVI标准数据,最后附加讲解了本人写的生成hdr文本文件代码。此外,文中还具体介绍写代码的一些思路。 一、读取ENVI头文件…...
如何对ppt文件设置修改权限?
PPT文件会应用在会议、演讲、课件等工作生活中,当我们制作好了PPT之后,保护内容防止在演示时出错是很重要的,那么如何将PPT文件设置成禁止修改模式呢?今天分享几个方法给大家。 方法一 将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实现多元时间序列预测,在本文中所提到的TPA和LSTM分别是注意力机制和深度学习模型,通过将其结合到一起实现时间序列的预测,本文利用…...
Mysql多表设计
前言 多表查询中要给每一表起别名 tableA as 别名1 , tableB as 别名2 ; (111111推荐) tableA 别名1 , tableB 别名2 ; 例子: 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运行时数据区梳理
学习笔记系列开头惯例发布一些寻亲消息 链接:https://baobeihuijia.com/bbhj/contents/3/192489.html 类装载器classLoader: 将本地的字节码文件.class 加载到内存方法区中成为元数据模板(两个class对象是否为同一个类要求:完整…...
Splunk 创建特色 dashboard 报表
1: 背景: 对原有的dashboard 进行增加点东西,特别是文字部分: 比如: 增加:“this is a guidline for how to use performance". 这段话,就不能写在title, 那样,这段文字,会出现在dashboard 的PDF 文件的分割线的上面,不符合要求。 2: 解决问题: 正确的做法是…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
