Vue nextTick使用场景及实现原理

nextTick是前端面试中vue框架中必考的部分,一定要掌握。它主要是处理我们再变更完数据以后,无法立刻拿到最新的DOM节点对象的问题。我们可以这样理解:vue执行完渲染后会执行this.nextTick()里面的callback函数。

 

使用场景

我们来看一个实际的vue组件

<template><div class="hello"><p ref="p_ref">当前姓名:<b>{{ name }}</b></p><button @click="changeName">改变名称</button></div>
</template><script>
export default {name: "Demo",data() {return {name: "张三",};},methods: {changeName() {this.name = "李四";console.log(this.$refs["p_ref"].innerHTML);},},
};
</script>

在这个组件中,我们定义了一个name属性和一个changeName方法,并给展示name属性绑定了名为“p_ref”的ref引用,这样我们就可以对该DOM节点进行操作。我们在changeName方法中,做了两件事情:首先我们改变了name属性的值,然后我们使用vue的this.$refs方法拿到了真实的dom节点,并打印了dom节点的内容,控制台打印的内容如下:

当前姓名:<b>张三</b>

 很显然这不是我们想要的数据,因为我们改变了组件属性中的name属性,这时候打印的名称应该是李四才对。 我们来用this.nextTick()方法来改写这个组件:

<template><div class="hello"><p ref="p_ref">当前姓名:<b>{{ name }}</b></p><button @click="changeName">改变名称</button></div>
</template><script>
export default {name: "Demo",data() {return {name: "张三",};},methods: {changeName() {this.name = "李四";this.$nextTick(() => {console.log(this.$refs["p_ref"].innerHTML);});},},
};
</script>

 我们做的事情很简单,我们使用了this.$nextTick()方法,并在函数中定义了一个箭头函数,然后在箭头函数里面打印p标签里面的内容,结果可以猜到:

 

当前姓名:<b>李四</b>

 

这就是this.$nextTick()的作用,帮助我们在改变组件中属性以后,立刻拿到渲染以后的dom节点对象,那它是怎么实现这一功能的呢?

实现原理

首先vue底层会定义一个callback数组来模拟事件队列,通过cb参数传入的函数会经过一个函数包装,在这个包装过程中会执行传入的函数,并处理执行失败的情况以及cb参数不存在的情况,包装完成后会添加到callbacks数组中;然后调用timerFunc函数,该函数就是用各种异步执行的方法调用flushCallbacks函数,在flushCallbacks函数中,将拷贝callbacks中的每一个函数并执行。vue会定义一个变量pending来保证一个事件循环中只调用一次timerFunc函数。 在这过程中,最关键的是如何定义timerFunc函数,因为在各个浏览器下对创建异步执行函数的方法各不相同,下面来介绍主要的方法。

Promise创建异步执行函数

判断方式为:执行typeof Promise 如果返回的是:function则表示支持promise。创建代码如下:

if (typeof Promise !== 'undefined' && isNative(Promise)) {const p = Promise.resolve()timerFunc = () => {   //timerFunc函数就是用各种异步执行的方法调用flushCallbacks函数。p.then(flushCallbacks)if (isIOS) setTimeout(noop)}isUsingMicroTask = true
} 

MutationObserve 创建异步执行函数 

if (!isIE && typeof MutationObserver !== 'undefined' &&(isNative(MutationObserver) ||MutationObserver.toString() === '[object MutationObserverConstructor]')
) {var counter = 1;var observer = new MutationObserver(flushCallbacks);var textNode = document.createTextNode(String(counter));observer.observe(textNode, {characterData: true});timerFunc = function() {counter = (counter + 1) % 2;textNode.data = String(counter);};isUsingMicroTask = true;
}

创建并返回一个新的MutationObserver,并吧flushCallbacks作为回调传入,在指定DOM发生变化后会执行传入的函数。

setImmediate 创建异步执行函数
if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {timerFunc = () => {setImmediate(flushCallbacks)}
} 

setImmediate仅支持IE10以上的浏览器

setTimeout 创建异步执行函数

 

timerFunc = () => {setTimeout(flushCallbacks, 0);}

兼容IE10一下的浏览器,由于是宏任务因此比较消耗资源。

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

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

相关文章

对齐大型语言模型与人类偏好:通过表示工程实现

1、写作动机&#xff1a; 强化学习表现出相当复杂度、对超参数的敏感性、在训练过程中的不稳定性&#xff0c;并需要在奖励模型和价值网络中进行额外的训练&#xff0c;导致了较大的计算成本。为了解决RL方法带来的上述挑战&#xff0c;提出了几种计算上轻量级的替代方案&…

el-select选项过多导致页面卡顿,路由跳转卡顿

问题&#xff1a;el-select数据量太大&#xff0c;导致渲染过慢&#xff0c;或造成页面卡顿甚至于卡死 卡顿原因&#xff1a;DOM中数据过多&#xff0c;超过内存限制 解决方法&#xff1a; 1.使用Virtualized Select 虚拟化选择器&#xff0c;页面就不卡了 2.el-select做分…

K8S四层代理Service-02

Service的四种类型使用 ClusterIP使用示例Pod里使用service的服务名访问应用 NodePort使用示例 ExternalName使用示例 LoadBalancer K8S支持以下4种Service类型&#xff1a;ClusterIP、NodePort、ExternalName、LoadBalancer 以下是使用4种类型进行Service创建&#xff0c;应对…

Datawhale 强化学习笔记(四)结合策略梯度和价值函数的 Actor-Critic 算法

策略梯度算法的缺点 采样效率低。由于使用的是蒙特卡洛估计&#xff0c;与基于价值算法的时序差分估计相比其采样速度必然是要慢很多的&#xff0c;这个问题在前面相关章节中也提到过。高方差。虽然跟基于价值的算法一样都会导致高方差&#xff0c;但是策略梯度算法通常是在估…

卡梅德-噬菌体肽库构建的流程与技术难度简述

噬菌体肽库构建技术是一种高效的蛋白质展示方法&#xff0c;广泛应用于抗体药物发现、抗原设计与疫苗研发等领域。本文将详细介绍噬菌体肽库的构建流程及其技术难度。 一、噬菌体肽库构建流程 基因合成与改造&#xff1a;首先&#xff0c;通过基因合成技术&#xff0c;将目标多…

使用k8s 配置 RollingUpdate 滚动更新实现应用的灰度发布

方案实现方式&#xff1a; RollingUpdate 滚动更新机制 当某个服务需要升级时&#xff0c;传统的做法是&#xff0c;先将要更新的服务下线&#xff0c;业务停止后再更新版本和配置&#xff0c;然后重新启动服务。 如果业务集群规模较大时&#xff0c;这个工作就变成了一个挑战…

HEGERLS智能物流机器人|场景为王 以存取为技术核心布局的仓储集群

随着物流需求的多样化、复杂化&#xff0c;四向穿梭车技术经过几年的蓬勃发展&#xff0c;正在各领域迎来愈加广泛的应用。河北沃克作为该领域的代表&#xff0c;凭借庞大的产品群、功能强大的软件系统以及资源丰富的生态合作伙伴体系实现了快速的发展。其中&#xff0c;海格里…

CSS实现三种常用的三角形效果

目录 前言 一、实现普通三角形效果 二、实现三角形的气泡框效果 三、实现空心三角形效果 四、总结 往期回顾 前言 CSS 提供了出色的方法可以实现基本的形状。本文就来看看如何使用这些方法来实现项目中常用的三种三角形效果。 一、实现普通三角形效果 实现步骤 &#…

cookie in selenium 定时更新token

1.selenium添加cookie访问 需要登录才能访问的链接 selenium 访问 “https://developer.org.com”&#xff0c;如果没登陆,则跳转到"https://console.org.com/login"&#xff0c;此时selenium取到的cookie的domain是&#xff1a;.console.org.com。 而domain 是 .c…

【Docker】Docker学习⑦ - Docker仓库之单机Dokcer Registry

【Docker】Docker学习⑦ - Docker仓库之单机Dokcer Registry 七、 Docker仓库之单机Dokcer Registry1 下载docker registry镜像2 搭建单机仓库2.1 创建授权使用目录2.2 创建用户2.3 验证用户密码2.4 启动docker registry2.5 验证端口和容器2.6 测试登录仓库2.7 在Server1登陆后…

每日一题——LeetCode1313.解压缩编码列表

这么简单的题目要说的这么复杂 nums里每相邻的两个元素nums[i]、nums[j]为一对&#xff0c;nums[i]表示nums[j]的次数 var decompressRLElist function(nums) {let res[]for(let i0,j1;j<nums.length-1;i2,j2){while(nums[i]--){res.push(nums[j])}}return res }; 消耗时…

Hudi0.14.0集成Spark3.2.3(Spark SQL方式)

1 整合Hive For users who have Spark-Hive integration in their environment, this guide assumes that you have the appropriate settings configured to allow Spark to create tables and register in Hive Metastore. 我们使用 Hive添加第三方jar包方式总结 中**{HIVE_H…

python实例100第36例:求100之内的素数

题目&#xff1a;求100之内的素数。 程序分析&#xff1a;素数是只能被1和他本身除尽的书。 程序源代码&#xff1a; 实例 #!/usr/bin/python # -*- coding: UTF-8 -*-# 输出指定范围内的素数# 用户输入数据 lower int(input("输入区间最小值: ")) upper int(i…

应用集成(iPaaS)和数据集成(ETL)高效协同的最佳实践

随着企业数字化的步伐加快&#xff0c;企业IT工程师和数据工程师在应用和数据集成方面的工作变得日益密切。IT工程师通常利用iPaaS&#xff08;Integration Platform as a Service&#xff09;来进行异构应用和数据的集成&#xff0c;而数据工程师则倾向于使用ELT/ETL&#xff…

Dify学习笔记-入门学习(二)

1、官方文档链接 https://docs.dify.ai/v/zh-hans/getting-started/readme 2、 Dify基础介绍 Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使开发者可以快速搭建生产级的生成…

【深度学习:Collaborative filtering 协同过滤】深入了解协同过滤:技术、应用与示例

此图显示了使用协作筛选预测用户评分的示例。起初&#xff0c;人们会对不同的项目&#xff08;如视频、图像、游戏&#xff09;进行评分。之后&#xff0c;系统将对用户对项目进行评分的预测&#xff0c;而用户尚未评分。这些预测基于其他用户的现有评级&#xff0c;这些用户与…

在Vite5.x中使用monaco-editor

Uncaught (in promise) Error: Unexpected usage at _EditorSimpleWorker.loadForeignModule 如果你像我这样报错,那一般是getWorker部分出问题了. 首先推个帖子: https://github.com/vitejs/vite/discussions/1791 然后是代码 不需要在vite.config.ts中做任何设置,也不用…

硬件基础:数字电路概述与基础门电路

什么是数字逻辑电路 数字电路是一种利用离散信号进行信息处理的电子电路系统。 它的核心特点是使用数字信号来执行算术运算和逻辑运算。数字电路的工作信号是离散的&#xff0c;通常只取两个值&#xff1a;高电平和低电平&#xff0c;分别代表数值“1”和“0”。 这种电路的基础…

CSS基本知识总结

目录 一、CSS语法 二、CSS选择器 三、CSS样式表 1.外部样式表 2.内部样式表 3.内联样式 四、CSS背景 1.背景颜色&#xff1a;background-color 2.背景图片&#xff1a;background-image 3.背景大小&#xff1a;background-size 4.背景图片是否重复&#xff1a;backg…

活动回顾丨云原生技术实践营上海站「云原生 AI 大数据」专场(附 PPT)

AI 势不可挡&#xff0c;“智算”赋能未来。2024 年 1 月 5 日&#xff0c;云原生技术实践营「云原生 AI &大数据」专场在上海落幕。活动聚焦容器、可观测、微服务产品技术领域&#xff0c;以云原生 AI 工程化落地为主要方向&#xff0c;希望帮助企业和开发者更快、更高效地…