Vue2视图更新流程

422 阅读1分钟

render函数

利用正则表达式解析template字符串,得到AST树。

juejin.cn/post/688719…

juejin.cn/post/688794…

juejin.cn/post/688828…

juejin.cn/post/688867…

juejin.cn/post/688962…

Watcher与Computed

watcher分为render watcher, user watcher 与lazy watcher(计算属性)

juejin.cn/post/685750…

juejin.cn/post/685707…

createElm

根据Vnode创建真实Dom

$vnode与_vnode

$vnode就是_parentVnode,在创建组件实例的时候,会传入占位符节点vnode作为其_parentVnode,__vnode为组件自身render函数获取的vnode。

如下:

parent.vue

son.vue

parent.vue的vnode的children值为[vnode (son), vnode (other)],在根据父组件vnode【递归】创建视图的时候,碰到son组件,会将children[0],即son组件在父组件中的占位符节点,传给son组件,在son组件实例中,被存为$vnode。

son组件内部的_vnode是son组件的render函数获取的。代表了son组件“真正”的结构。

通过$vnode与_vnode的关系,就可以理解Vue插槽的原理。

juejin.cn/post/686679…

juejin.cn/post/686792…

整体流程

createElm

createComponent

如果根据vnode创建过了组件实例就return true。

i为vnode.data内置的一系列hook中的init hook。hook内置的过程在vm.$createElement逻辑中。

_render与$createElement

_render函数会返回组件vnode,其传入的参数为vm.$createElement.

vm.$createElemt本质上调用的是createElement函数。

此函数往vnode中添加了一系列钩子,这是其具体过程。

createComponent

真正创建vnode的过程

其中涉及了异步组件:juejin.cn/post/688906…

installComponentHooks将一些钩子函数埋入vnode中

这里埋入了init等钩子。

在根据vnode创建组件实例的时候就会触发这个init钩子。

这里有一段child = vnode.componentInstance = createComponentInstanceForVnode,这里的child指的是当前vnode对应的组件实例。

举个例子,上文Parent.vue中有两个children, 即Son组件与Other组件。这里的vnode指的是Son占位符节点(vnode)child=vnode.componentInstancevnode就是vnode),child = vnode.componentInstance中vnode就是vnode。此时Son组件“真正”的_vnode还没有生成

children创建后再继续调用$mount也是一个递归的过程。

小结

理解视图生成的过程最终要的是理解$vnode与_vnode的关系。