• 001 vue响应式的异步渲染


    问题场景

        // DOM节点
        <template>
          <div>
            <div v-if="isShow" ref="show">{{data1}}</div>
            <div v-else ref="hidden">{{data2}}</div>
          </div>
        </template>
    
        <script>
          this.ishow = false
          console.log(this.$refs.hidden.offsetHeight)
        </script>

      此时,会打印出 undefined,很奇怪呀

    分析

      这是因为vue是数据驱动视图的,即数据更新之后,vue会自动去更新视图,但是这个更新是异步的。即当数据更新之后,试图还未更新,此时继续操作更新后的dom,就会出现和预期不一样的结果。

    什么叫异步呢

      当执行一段js代码时,引起了页面的数据变化,而这些数据变化会引起dom树的更新,但这个dom树的更新并不是立即执行的。此时,vue会将更新dom数的这一任务放到 异步更新队列 中去排队,在下一轮事件循环中执行。

    为什么vue采用异步更新策略呢

      一句话:为了提升vue的性能,减少资源消耗

      我们可能在uige方法中对dom操作n多次(比如for循环对dom进行操作),如果每次都立即对dom进行更新,那么dom会频繁更新,这显然效率低下,异步更新,可以实现多次操作dom,一次更新视图。

    nextTick()的使用:

      1. nextTick方法时解决上述异步问题的一个思路。this.$nextTick(callback)

      2. nextTick的核心是利用了如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JS 方法来模拟对应的微/宏任务的实现;

      3. 它将传入的回调函数放在微/宏任务队列中等待执行,我们将更新数据之后,对更新后dom的操作放在$nextTick中去执行,就可以保证在dom更新完成之后,实现对dom的操作(因为这一步在队列中排在dom更新之后)

    nextTick()的使用原理:

      nextTick内部对异步更新队列,按顺序采用Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替,进行降级处理。

        降级的目的:就是在环境支持的情况下,尽早的去更新dom。

        优先选择微任务的原因:在微任务中更新队列是会比在宏任务中更新少一次UI渲染的。

    nextTick的更新

      过程

        1. Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 中 观察到数据变化的 watcher 推送进这个队列。

        2. 如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据,避免不必要的计算和Dom操作。

        3. 而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。

      源码解析

        1. 数据变化时,通过notify通知watcher进行更新操作;

        2. 通过subs[i].update依次调用watcher的update(未更新视图);

        3. 将watcher放到队列中,在queueWatcher会根据watcher的id进行去重(多个属性依赖一个watcher),如果队列中没有该watcher就会将该watcher添加到队列中(未更新视图);

        4. 通过nextTick异步执行flushSchedulerQueue方法刷新watcher队列(更新视图)

  • 相关阅读:
    Tomcat安装和配置过程
    Java集合框架概述
    Hash表的原理
    Java 浅拷贝和深拷贝的理解和实现方式
    Nginx 配置上传文件大小
    将博客搬至CSDN
    vscode中设置vue代码片段
    底部标签栏获取token失败
    Eacharts K线报错问题
    阿里字体图标库在项目中引用
  • 原文地址:https://www.cnblogs.com/carreyBlog/p/16360077.html
Copyright © 2020-2023  润新知