为什么 createElm在 是组件渲染vnode时构建整个组件树的时候,是先子后父,而且需要创建父节点占位符? 如果是普通文本节点,是直接插入吗?
来源:3-5 patch(下)

慕码人4144975
2020-02-19
老黄问题有点多,非常抱歉!
function createElm (
vnode,
insertedVnodeQueue,
parentElm,
refElm,
nested,
ownerArray,
index
) {
// ...
if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
return
}
const data = vnode.data
const children = vnode.children
const tag = vnode.tag
if (isDef(tag)) {
// ...
vnode.elm = vnode.ns
? nodeOps.createElementNS(vnode.ns, tag)
: nodeOps.createElement(tag, vnode)
setScope(vnode)
/* istanbul ignore if */
if (__WEEX__) {
// ...
} else {
createChildren(vnode, children, insertedVnodeQueue)
if (isDef(data)) {
invokeCreateHooks(vnode, insertedVnodeQueue)
}
insert(parentElm, vnode.elm, refElm)
}
// ...
} else if (isTrue(vnode.isComment)) {
vnode.elm = nodeOps.createComment(vnode.text)
insert(parentElm, vnode.elm, refElm)
} else {
vnode.elm = nodeOps.createTextNode(vnode.text)
insert(parentElm, vnode.elm, refElm)
}
}
写回答
1回答
-
因为 createElm 整个过程就是一个树的深度递归过程,这个递归过程中,会把组件的 vnode 转成真实的 DOM 并插入到父元素 DOM 节点,对于组件 vnode,它的 DOM 对应的父元素节点就是它的占位符节点对应的父 DOM节点。
举个例子吧,
<div>
<comp-a></comp-a>
<span></span>
</div>
在 div 对应的 vnode 执行 createChildren 的时候,组件 CompA 在渲染过程中会生成 vnode,那么它对应的 DOM 最终会挂载到 div 上,而 span 对应的 vnode 就直接挂载到 div 上。
递归过程结束,最终整个组件树渲染生成的 DOM 会挂载到最外层 Vue 实例 $mount 挂载的那个根节点上。022020-02-20
相似问题