vue重构老项目时,对于vue源码的一些收获(1)

728 阅读1分钟

由于上一篇中说到的“对于vue源码的意外收获”这一小节内容比较多,索性单独挑出来另成一篇。

this.$nextTick

官方解释

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

代码分析

  1. 使用this.nextTick这一API时,代码会立即执行到Vue.prototype.nextTick这一API时,代码会立即执行到Vue.prototype.nextTick,继而调用nextTick方法 2.查看nextTick方法,如下图所示
    2.1 进入之后,将传进nextTick里的函数都放入一个匿名函数并在callback中保存,并在匿名函数中进行cb以及_resolve(步骤2.3详细讲)的非空判断
    2.2 在将cb保存之后,在timerFunc这一异步函数中执行,在执行之前进行判断是否是最后一次,从而达到批量处理的效果
    2.3 最后一步是支持promise链式调用,如果用户调用了this.$nextTick,但是并未在其中传值,并且本地支持promise,那么它将返回一个promise,并将resolve状态传给在函数顶部赋值的_resolve以供下次进入时调用 3.接着2.2的后续,在进入timerFunc后所发生的事情
    3.1 我们发现,在vue下载下来后就执行了此段代码(为了方便阅读,我删除了一些注释) 3.2 这一大段一共就是三个判断,流程如下,简要说明就是在选择优先级时,
    promise > MutationObserver >> setImmediate > setTimeout
  2. 接着3.2的后续,进入flushCallbacks函数
    这个函数倒没啥说的,pending改为false,防止后续重复执行,这里唯一有点好奇的就是里面为什么要做一次拷贝,
    分明可以像下面一次性执行完毕后再将数组清空的
function flushCallbacks () {
    pending = false;
    for (var i = 0; i < callbacks.length; i++) {
      callbacks[i]();
    }
    callbacks.length = 0;
  }

nextTick代码结构图

在项目中的使用

  • 在频繁的触发相同的DOM更新时,用此方法方便去判断来减少DOM更新
    使用场景:如之前文章中说过的jq写的地图组件上批量删除节点,并更新vue写的列表时,使用异步微任务将DOM更新时机后移,并在其中增加阀门的思路来减少DOM更新
  • 在请求比较多且彼此依赖的情况下使用,以此减少嵌套
    使用场景:在多个请求的结果彼此依赖时,使用promise的then方法来实现链式调用