vue源码解读-update如何将vnode转为dom

目录导航

我们在分析mount时候,最后抛出了两个问题,其中一个就是update函数拿到render生成的vNode后做了什么?

首先打开src\core\instance\lifecycle.js,找到_update函数,该函数在初始化时被挂载至vue


vue源码解读-update如何将vnode转为dom_第1张图片

该函数的入参为


和false

向下走,prevEl缓存了一份

;vm指向vue;prevVnode=undefined

if (!prevVnode)取值为true,调用vm.__patch__方法

首先找到文件src\platforms\web\runtime\patch.js

vue源码解读-update如何将vnode转为dom_第2张图片

    在该文件中导入的nodeOps是一个原生dom操作集合,如insertBefore、appendChild、createElement等

    baseModules和platformModules则是生成dom所需要的工具模块,他们最后的合集modules形如


vue源码解读-update如何将vnode转为dom_第3张图片

    createPatchFunction则是path的核心方法,该方法首先做了一次for循环


vue源码解读-update如何将vnode转为dom_第4张图片

循环结束后实际上相当于让cbs缓存了一份modules

之后将内部定义的私有方法patch返回到_update中并调用,也就是说,在_update中调用的就是createPatchFunction返回的函数,其接收的形参为


对应的实参为


函数调用依次向下执行


vue源码解读-update如何将vnode转为dom_第5张图片

由于oldVnode.nodeType=1,因此isRealElement=true,代码走向else逻辑

由于oldVnode.hasAttribute(SSR_ATTR)=false && hydrating=false

因此直接调用emptyNodeAt


该方法将返回一个vnode实例,生成的vnode如下,即


vue源码解读-update如何将vnode转为dom_第6张图片

接着拿到当前的

和body元素


vue源码解读-update如何将vnode转为dom_第7张图片

紧接着调用createElm,该方法的入参为


代码向下走


vue源码解读-update如何将vnode转为dom_第8张图片

isDef(tag)=true进入判断

nodeOps.createElement调用原生dom方法创建了div元素

setScope是一些作用域相关的操作,如style标签设置scoped后css只在当前页有效

__WEEX__=false走向else逻辑

createChildren则是真的children,将每一个children成员遍历执行createElm,也就是说,他的结果也是创建一些html标签,由于我们这里是空数组,故忽略

invokeCreateHooks则向data属性上安装了一些钩子

insert则调用原生domAPI向html中插入dom元素

此时我们的页面实际上有两个id为app的div元素

回到patch

isDef(vnode.parent)=false不进入代码块

isDef(parentElm)=true调用removeVnodes


vue源码解读-update如何将vnode转为dom_第9张图片

该方法的入参为


因此,for循环只会执行一次,调用removeAndInvokeRemoveHook


vue源码解读-update如何将vnode转为dom_第10张图片

该方法经过一系列的if判断最终会调用createRmCb,而createRmCb方法实际上是调用了元素domAPI的removeChild方法将其中一个id为app的元素删除

也就是说,_update的过程实际上就是调用原生domAPI对el指定的标签元素进行copy+remove操作



那么,如果是组件,又将如何被转化为dom呢?(组件vnode的dom化)

你可能感兴趣的:(vue源码解读-update如何将vnode转为dom)