4.4 虚拟Vnode映射成真实DOM - update

回到 updateComponent的最后一个过程,虚拟的DOMvirtual dom生成后,调用Vue原型上_update方法,将虚拟DOM映射成为真实的DOM

  1. updateComponent = function () {
  2. // render生成虚拟DOM,update渲染真实DOM
  3. vm._update(vm._render(), hydrating);
  4. };

从源码上可以知道,update主要有两个调用时机,一个是初次数据渲染时,另一个是数据更新时触发真实DOM更新。这一节只分析初次渲染的操作,数据更新放到响应式系统中展开。

  1. function lifecycleMixin() {
  2. Vue.prototype._update = function (vnode, hydrating) {
  3. var vm = this;
  4. var prevEl = vm.$el;
  5. var prevVnode = vm._vnode; // prevVnode为旧vnode节点
  6. // 通过是否有旧节点判断是初次渲染还是数据更新
  7. if (!prevVnode) {
  8. // 初次渲染
  9. vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false)
  10. } else {
  11. // 数据更新
  12. vm.$el = vm.__patch__(prevVnode, vnode);
  13. }
  14. }

update的核心是patch方法,而_patch来源于:

  1. // 浏览器端才有DOM,服务端没有dom,所以patch为一个空函数
  2. Vue.prototype.__patch__ = inBrowser ? patch : noop;

patch方法又是createPatchFunction方法的返回值,createPatchFunction内部定义了一系列辅助的方法,但其核心是通过调用createEle方法,createEle会调用一系列封装好的原生DOMAPI进行dom操作,创建节点,插入子节点,递归创建一个完整的DOM树并插入到Body中。这部分逻辑分支较为复杂,在源码上打debugger并根据实际场景跑不同的分支有助于理解这部分的逻辑。内容较多就不一一展开。