前端Vue 源码分析-逻辑层 (2)

继续input的数据流向,之前讲到了input中的Dep是保存了3个Watcher对象的引用,其中会有一个Watcher是跟整个页面的渲染有关系的,这个就是用来封装vnode的处理。

当遍历Dep这个保存Watcher数组的时候,会把Watcher加入到一个异步的队列中进行处理

代码进行了简化

function queueWatcher(watcher) {

  var id = watcher.id;

  if (has[id] == null) {

    has[id] = true;

    queue.push(watcher);

    nextTick(flushSchedulerQueue);

  }

}

function flushSchedulerQueue() {

    queue.sort(function(a, b) { return a.id - b.id; });

    for (index = 0; index ) {

      watcher = queue[index];

      id = watcher.id;

      has[id] = null;

      watcher.run();

    }

}

 

这里很关键的一个点就是针对queue进行了排序,原因就是其中有一个Wacher是保存了vnode了,因为最后一步才是vnode的对比更新。必须让前面的Watcher更新数据完毕后,最后vnode才能做真正的对比,不过computed的Wacher不会加入到这个队列中,它会再编译树中动态的执行。

当前面的Watcher执行完毕后,调到最后一个Watcher,可以看到对应的代码

vm._update(vm._render(), hydrating);

通过vm._render方法构建vnode

通过vm._update 对比vnode,并渲染到页面中

vm._render

初始化的时,会通过构建出来的JS描述树,生成初始vnode,去绘制初始页面。每次DOM变化的时候,我们还是需要重新构建这个描述树,通过这个描述树去构建新的vnode

这个描述树生成相当复杂,vue2内部专门会有一个AST是干这个事的

对应的结构是这样的,这个可以其实就是真实DOM树的一个结构映射了:

 

前端Vue 源码分析-逻辑层

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspspj.html