Vue.js源码分析(五)--update

_update

这个方法是干什么的呢,前面我们生成了vnode,下一步就是把vnode映射到真实的DOM节点上,这里包含了初次渲染和后面的更新渲染,拿首次渲染为例,整理参数之后会去调用vm.__patch__方法,接着会去判断浏览器环境或node.js上,前者转到patch函数的调用,后者返回一个空函数,因为在服务端是不存在DOM的。

让我们把目光转到patch函数上,他是createPatchFunction函数返回的结果:

export const patch: Function = createPatchFunction({ nodeOps, modules })

看一下函数签名,接受一个对象,前者是一些常见的DOM操作,后者则是对常见attributes的一些钩子函数的处理。

在createPatchFunction中定义了很多辅助函数,最后返回的还是一个patch,回顾整个过程,其实是使用了柯里化的技巧,整个createPatchFunction过程使用到的一些函数都是与平台强相关的,所以相当于把与平台强相关的内容体取出来集成到了createPatchFunction之中,在patch中可以忽视平台的差异化参数。

patch

略过一系列定义的函数,在800多行我们终于能看到patch的全貌:

  return function patch(oldVnode, vnode, hydrating, removeOnly) {
    ...
  }

由函数调用时:

vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);

第一个参数是真实的DOM,第二个则是之前的虚拟DOM,后面同样是涉及服务端渲染,暂时舍弃,默认为false。这是初始化的时候的调用,如果是更新过程,则调用如下:

vm.$el = vm.__patch__(prevVnode, vnode);

接着往下走,对于第一次渲染,会走到:

oldVnode = emptyNodeAt(oldVnode);

这里其实就是把真实的DOM转化为vnode,接着便是最重要的把vnode挂载到document内部,这里利用了createElm函数。

在createElm内部,我们又会遇到一个常见的错误:

warn(
  "Unknown custom element: <" +
    tag +
    "> - did you " +
    "register the component correctly? For recursive components, " +
    'make sure to provide the "name" option.',
  vnode.context
);

这里即组件没有注册时会出现的错误。

接着我们会转到一个很重要的逻辑,即创建真实的DOM节点:

      vnode.elm = vnode.ns
        ? nodeOps.createElementNS(vnode.ns, tag)
        : nodeOps.createElement(tag, vnode);
      setScope(vnode);

这里根据有无namespace分成两种,我们先看nodeOps.createElement,这其实就是我们用的dom的操作的简单封装,接着会走一个createChildren逻辑,即如果有子节点依次创建即可:

        createChildren(vnode, children, insertedVnodeQueue);

接着会使用:

        insert(parentElm, vnode.elm, refElm);

方法去在父节点添加子节点,同样对于insert方法,也只是对原生DOM的简单封装,只不过会做一些平台校验之类的额外工作。

当然对于顺序来说,还是先创建子节点,然后再去递归创建父节点,最终挂载到响应的位置。

destroy old

        if (isDef(parentElm)) {
          removeVnodes([oldVnode], 0, 0);
        } else if (isDef(oldVnode.tag)) {
          invokeDestroyHook(oldVnode);
        }

挂载成功还有最后一步,举例来说,这里我们会创建一个新的div id=app,而原来旧的div id=app的空姐的仍然存在,所以最后一步需要把旧的节点销毁,这样才走完了全部的数据驱动流程。

总结

数据驱动答题流程就这样结束了,当然这里至少简单分析了初次挂载,后面会更加深入的介绍,总体来说收获还是很大的,继续加油

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值