广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >vue异步更新dom的实现浅析
  • 520
分享到

vue异步更新dom的实现浅析

2024-04-02 19:04:59 520人浏览 安东尼
摘要

目录Vue异步更新DOM的原理1 什么时候能获取到真正的DOM元素?2 为什么Vue需要通过nextTick方法才能获取最新的DOM?3 为什么this.$nextTick 能够获取

Data对象:vue中的data方法中返回的对象;

Dep对象:每一个Data属性都会创建一个Dep,用来搜集所有使用到这个Data的Watcher对象;

Watcher对象:主要用于渲染DOM

Vue异步更新DOM的原理

Vue中的数据更新是异步的,意味着我们在修改完Data之后并不能立刻获取修改后的DOM元素。

1 什么时候能获取到真正的DOM元素?

  在Vue的nextTick回调中。

2 为什么Vue需要通过nextTick方法才能获取最新的DOM?

2.1 vue在调用Watcher更新视图时,并不会直接进行更新,而是把需要更新的Watcher加入到Queue队列里,然后把具体的更新方法flushSchedulerQueue 传给nexTick 进行调用。


// src > core > observer > watcher.js + scheduler.js// 当一个 Data 更新时,会依次执行以下代码
// 1. 触发 Data.set
// 2. 调用 dep.notify
// 3. Dep 会遍历所有相关的 Watcher 执行 update 方法
class Watcher {
  // 4. 执行更新操作
  update() {
    queueWatcher(this);
  }
}

const queue = [];

function queueWatcher(watcher: Watcher) {
  // 5. 将当前 Watcher 添加到异步队列
  queue.push(watcher);
  // 6. 执行异步队列,并传入回调
  nextTick(flushSchedulerQueue);
}

// 更新视图的具体方法
function flushSchedulerQueue() {
  let watcher, id;
  // 排序,先渲染父节点,再渲染子节点
  // 这样可以避免不必要的子节点渲染,如:父节点中 v-if 为 false 的子节点,就不用渲染了
  queue.sort((a, b) => a.id - b.id);
  // 遍历所有 Watcher 进行批量更新。
  for (index = 0; index < queue.length; index++) {
    watcher = queue[index];
    // 更新 DOM
    watcher.run();
  }
}

2.2 nextTick -- 将传入的flushSchedulerQueue 添加到callbacks 数组中,然后执行了timerFunc 方法。


const callbacks = [];
let timerFunc;

function nextTick(cb?: Function, ctx?: Object) {
  let _resolve;
  // 1.将传入的 flushSchedulerQueue 方法添加到回调数组
  callbacks.push(() => {
    cb.call(ctx);
  });
  // 2.执行异步任务
  // 此方法会根据浏览器兼容性,选用不同的异步策略
  timerFunc();
}

2.3 timerFunc方法 -- 是根据浏览器兼容性创建的一个异步方法,执行完该方法就会调用flushSchedulerQueue 方法进行具体的DOM更新。


let timerFunc;
// 判断是否兼容 Promise
if (typeof Promise !== "undefined") {
  timerFunc = () => {
    Promise.resolve().then(flushCallbacks);
  };
  // 判断是否兼容 MutationObserver
  // https://developer.mozilla.org/zh-CN/docs/WEB/api/MutationObserver
} else if (typeof MutationObserver !== "undefined") {
  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);
  };
  // 判断是否兼容 setImmediate
  // 该方法存在一些 IE 浏览器中
} else if (typeof setImmediate !== "undefined") {
  // 这是一个宏任务,但相比 setTimeout 要更好
  timerFunc = () => {
    setImmediate(flushCallbacks);
  };
} else {
  // 如果以上方法都不知道,使用 setTimeout 0
  timerFunc = () => {
    setTimeout(flushCallbacks, 0);
  };
}

// 异步执行完后,执行所有的回调方法,也就是执行 flushSchedulerQueue
function flushCallbacks() {
  for (let i = 0; i < copies.length; i++) {
    callbacks[i]();
  }
}

2.4 完善逻辑判断

2.4.1 判断has 标识,避免在一个Queue 中添加相同的Watcher;

2.4.2 判断waiting 标识,让所有的Watcher 都在一个tick 内进行更新;

2.4.3 判断flushing 标识,处理Watcher 渲染时,可能产生的新Watcher。

  如触发了v-if 条件,新增的Watcher 渲染。

tip:nextTick 只是单纯通过Promise、setTimeout等方法模拟的异步任务。

3 为什么this.$nextTick 能够获取更新后的DOM?

  调用this.$nextTick 其实就是调用图中的nextTick 方法,在异步队列中执行回调函数。根据先进先出原则,修改Data 触发的更新异步队列会先得到执行,执行完成后就生成了新的DOM,接下来执行this.$nextTick 的回调函数时,能获取到更新后的DOM元素了。


// 我们使用 this.$nextTick 其实就是调用 nextTick 方法
Vue.prototype.$nextTick = function (fn: Function) {
  return nextTick(fn, this);
};

总结:vue异步更新的原理

修改 Vue 中的 Data 时,就会触发所有和这个 Data 相关的 Watcher 进行更新。首先,会将所有的 Watcher 加入队列 Queue。然后,调用 nextTick 方法,执行异步任务。在异步任务的回调中,对 Queue 中的 Watcher 进行排序,然后执行对应的 DOM 更新。

到此这篇关于vue异步更新dom的实现浅析的文章就介绍到这了,更多相关vue异步更新dom内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: vue异步更新dom的实现浅析

本文链接: https://www.lsjlt.com/news/129911.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • vue异步更新dom的实现浅析
    目录Vue异步更新DOM的原理1 什么时候能获取到真正的DOM元素?2 为什么Vue需要通过nextTick方法才能获取最新的DOM?3 为什么this.$nextTick 能够获取...
    99+
    2022-11-12
  • Vue批量更新dom的实现步骤
    目录场景介绍深入响应式触发getter寻找Dep.targetgettersetter总结场景介绍 在一个SFC(single file component,单文件组件)中,我们经...
    99+
    2022-11-12
  • Vue异步更新DOM及$nextTick执行机制源码分析
    本篇内容介绍了“Vue异步更新DOM及$nextTick执行机制源码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Vue异步更新DOM策...
    99+
    2023-07-05
  • 浅析Angular变更检测中的DOM更新机制
    变更检测是Angular中很重要的一部分,也就是模型和视图之间保持同步。在日常开发过程中,我们无需了解变更检测,因为Angular都帮我们完成了这一部分工作,让开发人员更加专注于业务实现,提高开发效率和开发体验。但是如果想要深入使用框架,或...
    99+
    2023-05-14
    DOM更新机制 变更检测 前端 Angular.js
  • Vue异步更新DOM及$nextTick执行机制解读
    目录Vue异步更新DOM策略$nextTick执行机制示例详解Vue异步更新DOM的目的$nextTick应用示例总结Vue异步更新DOM策略 我们知道,Vue实现响应式并不是数据发...
    99+
    2023-03-24
    Vue异步更新DOM $nextTick执行机制 Vue异步更新
  • Vue组件渲染与更新实现过程浅析
    目录1. 模板编译2. 组件渲染和更新1. 模板编译 Vue的模板编译就是将模板字符串转换为渲染函数的过程。具体来说,当组件的生命周期执行到created和beforeMounted...
    99+
    2023-03-03
    Vue组件渲染 Vue组件更新
  • Vue nextTick获取更新后的DOM的实现
    目录生命周期 updateVue.nextTickPromise结语&参考资料前两天在开发时遇到一个需求:打开对话框的时候自动聚焦其中的输入框。由于原生的 autofocus...
    99+
    2022-11-13
  • Vue异步更新机制和nextTick原理实例分析
    这篇文章主要介绍“Vue异步更新机制和nextTick原理实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue异步更新机制和nextTick原理实例分析”文章能帮助大家解决问题。1. 异步更...
    99+
    2023-06-27
  • 浅析Vue中Virtual DOM和Diff原理及实现
    目录0. 写在开头1. vdom2. Diff0. 写在开头 本文将秉承Talk is cheap, show me the code原则,做到文字最精简,一切交由代码说明! 1. ...
    99+
    2023-03-21
    Vue Virtual DOM Diff原理 Vue Virtual DOM Vue Diff
  • vue的状态更新方式(异步更新解决)
    目录状态更新(异步更新解决)解决方案异步更新及nexttick为什么需要异步更新nextTick 原理状态更新(异步更新解决) 在vue中状态更新是异步的,这一点和react中的se...
    99+
    2022-11-13
  • Vue nextTick如何获取更新后的DOM的实现
    这篇文章将为大家详细讲解有关Vue nextTick如何获取更新后的DOM的实现,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。前两天在开发时遇到一个需求:打开对话框的时候自动聚焦其...
    99+
    2023-06-28
  • vue源码之批量异步更新策略的深入解析
    vue异步更新源码中会有涉及事件循环、宏任务、微任务的概念,所以先了解一下这几个概念。 一、事件循环、宏任务、微任务 1.事件循环Event Loop:浏览器为了协调事件处理、脚本...
    99+
    2022-11-12
  • Ajax实现网页异步更新的方法
    这篇文章主要讲解了“Ajax实现网页异步更新的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Ajax实现网页异步更新的方法”吧!   1:ajax的概...
    99+
    2022-10-19
  • Vue 中异步更新的原理是什么
    今天就跟大家聊聊有关Vue 中异步更新的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Vue 异步更新 DOM 原理很多同学都知道,Vue...
    99+
    2022-10-19
  • 浅析Angular变更检测中的订阅异步事件
    在上一篇文章中,我们介绍了具体什么是变更检测,用一个原生JS例子来更好的去理解变更检测,以及介绍了在哪些场景下会触发变更检测。前文中总结了5种工作中常见的场景,但是我们需要先思考一下,Angular的变更检测是否支持所有的异步事件呢?如果支...
    99+
    2023-05-14
    订阅异步事件 Angular 变更检测
  • Flutter如何轻松实现动态更新ListView浅析
    目录前言数据集触发器展示视图完整代码总结前言 在 App 开发过程中,ListView 是 比较很常见的控件,用来处理 列表类的数据展示。当然 Flutter 也是支持的,由于 Fl...
    99+
    2022-11-13
  • Vue异步更新机制和nextTick的原理是什么
    本篇内容介绍了“Vue异步更新机制和nextTick的原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所...
    99+
    2022-10-19
  • electron-vue+electron-updater实现自动更新(步骤源码)
    目录1、autoUpdater.js      (操控更新js文件)2、main.js(也就是package.json内的main指向的js文...
    99+
    2022-11-13
    electron-vue自动更新 electron-updater自动更新
  • Vue异步更新机制及$nextTick原理的深入讲解
    目录前言Vue的异步更新DOM更新是异步的DOM更新还是批量的事件循环执行过程源码深入异步更新队列nextTick$nextTick总结一般更新DOM是同步的既然更新DOM是个同步的...
    99+
    2022-11-13
  • 浅析golang是如何实现同步的
    随着开发语言的不断发展,现在越来越多的公司开始采用golang作为其主要的开发语言。由于其高效且并发性好的特点,golang已经在很多领域发挥了非常重要的作用。但是,在并发处理时,我们不可避免地遇到同步问题,如果这些问题没有得到很好的处理,...
    99+
    2023-05-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作