页面初始化的所有状态都准备就绪之后,下一步就是要生成组件相应的虚拟节点—— VNode 。初次进行组件初始化的时候, VNode 也会执行一次初始化并存储这时创建好的虚拟节点对象。在随后的生命周期中,组件内的数据发生变动时,会先生成新的 VNode 对象,然后再根据与之前存储的旧虚拟节点的对比来执行刷新页面 DOM 的操作。页面刷新的流程大致上可以这样简单的总结,但是其实现路程是非常复杂的,为了深入地了解虚拟节点生成和更新的过程,首先来看看 VNode 类的具体实现。
VNode 类
VNode 类的实现是支持页面渲染的基础,这个类的实现并不复杂,但无论是创建Vue组件实例还是使用动态JS扩展函数组件都运用到了渲染函数 render ,它充分利用了 VNode 来构建虚拟DOM树。
// 定义并导出VNode类
export default class VNode {
// 定义实例属性
tag: string | void; // 标签名称
data: VNodeData | void; // 节点数据
children: ?Array<VNode>; // 子虚拟节点列表
text: string | void; // 节点文字
elm: Node | void; // 对应DOM节点
ns: string | void; // 节点命名空间,针对svg标签的属性
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
// 是否包含原始HTML。只有服务器端会使用
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
// 方法作用域id










