请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

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

老黄问题有点多,非常抱歉!

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节点。
https://img1.sycdn.imooc.com//szimg/5e4cf6860916d52c22301156.jpg
举个例子吧,
<div>
   <comp-a></comp-a>
  <span></span>
</div>

在 div 对应的 vnode 执行 createChildren 的时候,组件 CompA  在渲染过程中会生成 vnode,那么它对应的 DOM 最终会挂载到 div 上,而 span 对应的 vnode 就直接挂载到 div 上。

递归过程结束,最终整个组件树渲染生成的 DOM 会挂载到最外层 Vue 实例 $mount 挂载的那个根节点上。

0 回复 有任何疑惑可以回复我~
  • 提问者 慕码人4144975 #1
    感谢老黄,永远支持老黄继续创作!这个父占位符节点有点抽象,我理解错了!还是简单的例子容易理解
    回复 有任何疑惑可以回复我~ 2020-02-19 22:15:44
  • ustbhuangyi 回复 提问者 慕码人4144975 #2
    确实有点抽象,所以希望你在学习的时候也自己手写一些小例子来配合理解。
    回复 有任何疑惑可以回复我~ 2020-02-20 10:26:19
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信