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

2020-06-16 06:58:15易采站长站整理
用的静态类型检测的方式是
flow
,所以它会借助
flow
实现自定义类型。而
VNode
就是其中一种。那么,我们看看
VNode
类型定义:

前面,我们分析了

createElement()
的调用时机,知道它最终返回的就是 VNode。那么,现在我们来看看
VNode
的定义:


export default class VNode {
tag: string | void;
data: VNodeData | void;
children: ?Array<VNode>;
text: string | void;
elm: Node | void;
ns: string | void;
context: Component | void; // rendered in this component's scope
key: string | number | void;
componentOptions: VNodeComponentOptions | void;
componentInstance: Component | void; // component instance
parent: VNode | void; // component placeholder node

// strictly internal
raw: boolean; // contains raw HTML? (server only)
isStatic: boolean; // hoisted static node
isRootInsert: boolean; // necessary for enter transition check
isComment: boolean; // empty comment placeholder?
isCloned: boolean; // is a cloned node?
isOnce: boolean; // is a v-once node?
asyncFactory: Function | void; // async component factory function
asyncMeta: Object | void;
isAsyncPlaceholder: boolean;
ssrContext: Object | void;
fnContext: Component | void; // real context vm for functional nodes
fnOptions: ?ComponentOptions; // for SSR caching
devtoolsMeta: ?Object; // used to store functional render context for devtools
fnScopeId: ?string; // functional scope id support

constructor (
tag?: string,
data?: VNodeData,
children?: ?Array<VNode>,
text?: string,
elm?: Node,
context?: Component,
componentOptions?: VNodeComponentOptions,
asyncFactory?: Function
) {
...
}
...
}

可以看到 VNode 所具备的属性还是蛮多的,本次我们就只看

VNode
前面三个属性:

tag,即 VNode 对于的标签名
data,即 VNode 具备的一些属性
children,即 VNode 的子节点,它是一个 VNode 数组

显而易见的是

VNode
的设计也是一个
root
,然后由
children
不断延申下去。这样和前面
createElement()
的设计相呼应, 不可能会 出现多
root
的情况。