vue2中的$nextTick原理和简单实现

一、原理
1.1、它的原理涉及到 Vue.js 的异步更新队列机制;
1.2、在 Vue.js 中,当数据变化时,Vue 实例会异步执行更新。具体的更新过程是:
触发数据变化,触发响应式 getter。
通过 Dep(依赖管理器)进行依赖收集。
数据发生变化时,通知相关的 watcher。
watcher 将回调函数放入异步更新队列。
而 $nextTick 就是在这个异步更新队列执行完毕后被调用的。它的作用是在 DOM 更新之后执行回调函数,确保你在回调中访问的是更新后的 DOM

1.3、$nextTick 利用了 JavaScript 引擎的事件循环机制,将回调函数推迟到下一个事件循环中执行,以确保在 DOM 更新完成后执行(简单来说就是利用微任务和宏任务)

1.4、在 Vue 3 中,$nextTick 被移除了,而是直接使用 nextTick 方法,用法和原理基本类似

二、实现方式(Promise、MutationObserver、setTimeout)

在现代浏览器中,this.$nextTick 使用了 Promise 或 MutationObserver 来实现微任务的触发。在不支持 Promise 和 MutationObserver 的环境中,会回退到使用 setTimeout 作为宏任务
以下是简单实现代码

Vue.prototype.$nextTick = function (callback) {
  // 将回调函数存入队列
  callbacks.push(callback)
  if (!pedding) { 
    pedding = true
    if (usePromise) {
      // 在promise微任务中调用
      Promise.resolve().then(fullCallback)
    } else if (useMutationObserver) {
     // 在MutationObserver宏任务中调用
      const oberser = new MutationOnserver(fullCallback)
      // 创建文本节点
      const textNode = document.createrTextNode('1')
      // 观察文本节点的data属性变化
      // obserse 第一个参数,需要监听的节点;第二个参数 监听检点的类型
      // characterData: 文字类型
      // attributes:表示监测元素属性的变化
      // childList: 表示监测子节点的增加或删
      // subtree: 表示监测整个子树
      // eg: observer.observe(targetElement, { attributes: true, childList: true, subtree: true })
      oberser.obserse(textNode, { characterData: true })
      // 修改文本节点的data属性,触发回调
      textNode.data = '2'
    } else {
      // 在不支持Promise和MutationObserver微任务调用时,回退到setTimeout宏任务调用
      setTimeout(fullCallback, 0)
    }
  }
}
function fullCallback() {
 // 循环调用回调函数
 for (let i = 0; i < callbacks.length; i++) {
   callbacks[i]()
 }
 // 重置状态
 callbacks = []
 pedding = false
}

三、MutationObserver不支持IE11以下的版本,兼容方式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Polyfill Example</title>
  <!-- 引入 Polyfill 库 -->
  <script src="path/to/mutation-observer-polyfill.js"></script>
</head>
<body>

<!-- 页面内容 -->

<script>
  // 在这里使用 MutationObserver,即使浏览器不支持也可以正常工作
  const observer = new MutationObserver(callback);
  observer.observe(targetElement, { attributes: true, childList: true, subtree: true });
</script>

</body>
</html>

mutation-observer-polyfill.js 是 MutationObserver 的 Polyfill 库。通过在页面中引入这个 Polyfill,我们确保了即使浏览器不原生支持 MutationObserver,我们仍然可以在代码中使用它。Polyfill 会自动检测浏览器支持情况
四、宏任务(macrotask)和微任务(microtask)
4.1、宏任务包括事件处理、setTimeout、setInterval 等
4.2、微任务包括Promis、MutationObserver
4.3、微任务比宏任务先执行
五、时间循环机制(Event Loop)
5.1、事件循环(Event Loop)是 JavaScript 引擎处理异步操作的一种机制,它使得 JavaScript 能够处理并发的任务而不阻塞后续代码的执行。在浏览器中,事件循环是浏览器实现的,而在 Node.js 中,事件循环是由 Node.js 运行时提供的
在这里插入图片描述

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值