nextTick的更新原理

场景和用法

场景:数据变化之后想要获取更新之后的最新的dom

  • 因为数据变化之后,组件的更新watcher 并不是同步执行的,而是通过nextTick放到异步队列里面等待执行【同步代码走完之后才会执行】
  • 数据发生变化之后,组件更新的watcher也是通过nextTick进行异步更新
原理
  1. 数据发生变化之后,触发当前数据的set方法【初始化的时候已经进行get和set的劫持了】
  2. set方法内部会执行dep.notify【通知收集到的依赖进行更新】
  3. notify方法内部,会遍历subs【收集到的依赖数组】,进行更新【watcher.update】

  1. watcher.update:调用queueWatcher(wacher)【当前更新的watcher实例】
  2. queueWatcher方法:获取当前watcherid【唯一值】
    1. 判断当前wathcer是否已经被添加,对 会wathcer 进行去重
    2. 如果没有添加到队列里面 >> 进行添加 >> queue里面push进去当前组件的更新watcher
    3. 调用nextTick方法,把flushSchedulerQueue【可以更新queue里面的所有的watcher,调用的是watcher的run方法 >> run方法的作用,就行执行页面的更新】
nextTick(flushSchedulerQueue)

function flushSchedulerQueue() {
  for (let i = 0; i < queue.length; i++) {
    queue[i].run(); // 可以更新页面
  }
  queue = []; // [watcher1, watcher2, watcher3, ....]
  has = {};
}

        

  nextTick的实现

  ===> nextTick执行传入的回调的时候不是同步执行,而是异步执行

function nextTick(fn) {
  callback.push(fn)
}
  • 往callbacks里面push进去当前flushSchedulerQueue
  • 全局会定义一个pending标识,分批更新
  • 如果这个标识为false,证明目前没有更新的队列 >> 可以执行更新
  • 异步任务执行的时候,根据当前的宿主环境判断异步任务类型【promise的优先级最高】===========> Promise/mutationObserver/setImidate/setTimeout
  • 同步代码走完之后,开始执行异步队列里面存储进去的异步任务,实现更新

代码举例

<template>
  <div id="app">
    {{ msg }} {{ age }}
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      msg: 'msg',
      age: 10
    }
  },
  mounted() {
    console.log(this)
  },
  methods: {
    show() {
      this.age = 20
      this.$nextTick(() => {
        console.log(document.querySelector('#app').innerHTML); // newMsg
      })
      this.msg = 'newMsg';
    }
  }
}
</script>

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值