Vue 中 template 有且只能一个 root的原因解析(源码分(3)

然后,继续遍历。对于 <span> 也会创建一个 ASTElement 并入栈,然后删除继续下一次。接下来,会匹配到 </span> ,此时会处理标签的结束,例如于栈顶 ASTElement 的 tag 进行匹配,然后出栈。接下来,匹配到 </div> ,进行和 span 同样的操作。

最后,对于第二个 root 的 <div> ,会做和上面一样的操作。但是,在处理 </div> 时,此时会进入判断 multiple root 的逻辑,即此时字符串已经处理完了,但是这个结束标签对应的 ASTElement 并不等于我们最初定义的 root 。所以此时就会报错:

Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

而且,该 ASTElement 也不会加入最终的 AST 中,所以之后也不可能会出现多个 root 的情况。

同时,这个报错也提示我们如果要用多个 root ,需要借助 if 条件判断来实现。

可以看出, template 编译的最终的目标就是构建一个 AST 抽象语法树。所以,它会在创建第一个 ASTElement 的时候就确定 AST 的 root ,从而确保 root 唯一性。

2.2 _render 过程

不了解 Vue 初始化过程的同学,可能不太清楚 _render 过程。你可以理解为渲染的过程。在这个阶段会调用 render 方法生成 VNode ,以及对 VNode 进行一些处理,最终返回一个 VNode 。

而相比较 template 编译的过程, _render 过程的判断就比较简洁:

if (!(vnode instanceof VNode)) { if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) { warn( 'Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm ); } vnode = createEmptyVNode(); }

前面在讲 createElement 的时候,也讲到了 render() 需要返回 VNode 。所以,这里是防止部分骚操作, return 了包含多个 VNode 的数组。

结语

通过阅读,我想大家也明白了 为什么 Vue 中 template 有且只能一个 root ? 。 Vue 这样设计的出发点可能很简单,为了减少挂载时 DOM 的操作。但是,它是如何处理多 root 的情况,以及相关的 VNode 、 AST 、 createElement() 等等关键点,个人认为都是很值得深入了解的。

到此这篇关于Vue 中 template 有且只能一个 root的原因解析(源码分析)的文章就介绍到这了,更多相关vue template 有且只能一个 root内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/befc2b0536e89eabdd15bd1b5fd47bd9.html