前言:因为生活一些琐事,好久没有更新公众号文章了,打算从今天起慢慢拾起来。
众所周知,期待已久的Vue3.0已经发布了,更新了很多特性,其中有一条:支持多个子节点 fragment。那我们就来探讨下为什么2.0只能有一个根节点。
看了vue源码后,我的理解是我们在new Vue时候需要传入一个el(不传的话vue实例不知道该替换那个div),这个如果我们参数没有传入template就会取他的outHtml作为template,经过compile 中parseHtml编译为ast语法树然后在生成render函数再去生成vnode,最后domdiff更新页面。那么既然是语法树自然只能有一个根节点,只有一个入口。
我们使用脚手架写vue时,写在tempalte下为什么也不能有多个div呢。那我们首先要了解下tempalte.他主要有3个特性
1.内容隐藏性:该标签不会显示在页面的任何地方,即便里面有多少内容,它永远都是隐藏的状态,;
2.位置任意性:该标签可以写在页面的任何地方,甚至是head、body、sciprt标签内;
3.childNodes无效性:该标签里的任何HTML内容都是无效的,不会起任何作用
但是我们可以通过innerHTML取出里面内容,我们知道template最终也会被编译为vnode,那么那里面内容自然也需要唯一入口了。所以template里面也只能有一个根元素。
总而言之,我们既然已经知道Vue内部需要一个树结构vnode,那我们讨论几个根节点其实也没有什么意义。vue2.0内部构建和diff不支持多个根节点(如果允许多个节点的话,就需要diff一个数组,而数组的diff 不加key则会出现效率问题)。