12-02 vue异步更新的原理(异步更新的优点,执行机制)

  • Data对象:Vue中的Data方法返回的对象。
  • Dep对象:每一个Data属性都会创建一个Dep,用来搜集所有使用到这个Data的Watcher对象。
  • Watcher对象:主要用于渲染。
  • <template>
      <div>
        <span id="text">{{ message }}</span>
        <button @click="changeData">changeData</button>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          message: "hello",
        };
      },
      methods: {
        changeData() {
          this.message = "hello world";
          const textContent = document.getElementById("text").textContent;
          // 直接获取,不是最新的
          console.log(textContent === "hello world"); // false
          // $nextTick 回调中,是最新的
          this.$nextTick(() => {
            const textContent = document.getElementById("text").textContent;
            console.warn(textContent === "hello world"); // true
          });
        },
      },
    };
    </script>

  • 什么时候我们才能获取真正的DOM元素?
  • 答: 在Vue的nextTick中

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

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


 

1.修改数据时,会先将所有的依赖都放在 queue(异步队列中)

2.调用nextTick方法,将所有回调函数都添加在callbacks 这个数组中,执行timerFunc,根据浏览器的兼容性,来创建一个异步任务

3.异步完成后,执行对应的回调,对依赖进行排序,然后执行run()方法,对dom进行更新

优势:   

最直白的答案就是因为性能考虑

如果每次对 data 数据的写操作都将调用一次同步的组件更新,这在许多场景会引起性能问题。Vue 作为底层的构建视图层方案,在实际场景中肯定是假设用户会尽可能多的触发更新,那好的策略就是尝试将多次更新合并成一次统一操作然后提交 DOM 变更。

我们给父子组件同时绑定了点击事件处理函数,而当子组件触发了点击事件后,我们在父子组件的事件函数中会同时触发当前组件视图更新的操作,但我们肯定不希望在这两个先后事件处理的过程中要重复渲染两次子组件,这时就可以将它们标记成“待更新状态”(wait for flush),然后在合适的时机交由调度器一起重新渲染它们。

此外还有例如手势拖拽、滚动事件处理这种强交互场景,不做批处理更新都容易产生瓶颈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值