likes
comments
collection
share

50+Vue经典面试题源码级详解(26)

作者站长头像
站长
· 阅读数 13

前言

小伙伴们好,这是村长《Vue经典面试题源码级详解》系列文章第26题,前面已完成题目合集在此: 历时一个月,2.6W字!50+Vue经典面试题源码级详解,你值得收藏!

学习群

我组织了一个面试学习群,关注村长公众号村长学前端,回复“加群”,大家一起卷~

相关学习资源

本系列有配套视频思维导图开源项目,大家学习同时千万不要忘了三连 + 关注 + 分享,有道是喝水不忘挖井人~

Vue组件为什么只能有一个根元素?

这题现在有些落伍,vue3已经不用一个根了。因此这题目很有说头!


体验一下

vue2直接报错,test-v2.html

new Vue({
  components: {
    comp: {
      template: `
        <div>root1</div>
        <div>root2</div>
      `
    }
  }
}).$mount('#app')

50+Vue经典面试题源码级详解(26)


vue3中没有问题,test-v3.html

Vue.createApp({
  components: {
    comp: {
      template: `
        <div>root1</div>
        <div>root2</div>
      `
    }
  }
}).mount('#app')

50+Vue经典面试题源码级详解(26)


回答思路

  • 给一条自己的结论
  • 解释为什么会这样
  • vue3解决方法原理

范例

  • vue2中组件确实只能有一个根,但vue3中组件已经可以多根节点了。
  • 之所以需要这样是因为vdom是一颗单根树形结构,patch方法在遍历的时候从根节点开始遍历,它要求只有一个根节点。组件也会转换为一个vdom,自然应该满足这个要求。
  • vue3中之所以可以写多个根节点,是因为引入了Fragment的概念,这是一个抽象的节点,如果发现组件是多根的,就创建一个Fragment节点,把多个根节点作为它的children。将来patch的时候,如果发现是一个Fragment节点,则直接遍历children创建或更新。

知其所以然

  • patch方法接收单根vdom:

    github1s.com/vuejs/core/…

    // 直接获取type等,没有考虑数组的可能性
    const { type, ref, shapeFlag } = n2
    
  • patch方法对Fragment的处理:

    github1s.com/vuejs/core/…

    // a fragment can only have array children
    // since they are either generated by the compiler, or implicitly created
    // from arrays.
    mountChildren(n2.children as VNodeArrayChildren, container, ...)
    

写在最后

既然看到这里了,点个赞鼓励一下作者吧。

小伙伴们有不同的见解欢迎在评论区留言~

咱们下期再见!