render函数
利用正则表达式解析template字符串,得到AST树。
Watcher与Computed
watcher分为render watcher, user watcher 与lazy watcher(计算属性)
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插槽的原理。
整体流程
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。此时Son组件“真正”的_vnode还没有生成。
children创建后再继续调用$mount也是一个递归的过程。
小结
理解视图生成的过程最终要的是理解$vnode与_vnode的关系。