DOM“天生就慢”,所以前端各大框架都提供了对DOM操作进行优化的办法,Angular中的是脏值检查,React首先提出了Virtual Dom,Vue2.0也加入了Virtual Dom,与React类似。
本文将对于Vue 2.5.3版本中使用的Virtual Dom进行分析。
updataChildren是Diff算法的核心,所以本文对updataChildren进行了图文的分析。
1.VNode对象
一个VNode的实例包含了以下属性,这部分代码在src/core/vdom/vnode.js里
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; functionalContext: Component | void; // real context vm for functional nodes functionalOptions: ?ComponentOptions; // for SSR caching functionalScopeId: ?string; // functioanl scope id support
- tag: 当前节点的标签名
- data: 当前节点的数据对象,具体包含哪些字段可以参考vue源码types/vnode.d.ts中对VNodeData的定义
- children: 数组类型,包含了当前节点的子节点
- text: 当前节点的文本,一般文本节点或注释节点会有该属性
- elm: 当前虚拟节点对应的真实的dom节点
- ns: 节点的namespace
- context: 编译作用域
- functionalContext: 函数化组件的作用域
- key: 节点的key属性,用于作为节点的标识,有利于patch的优化
- componentOptions: 创建组件实例时会用到的选项信息
- child: 当前节点对应的组件实例
- parent: 组件的占位节点
- raw: raw html
- isStatic: 静态节点的标识
- isRootInsert: 是否作为根节点插入,被
- isComment: 当前节点是否是注释节点
- isCloned: 当前节点是否为克隆节点
- isOnce: 当前节点是否有v-once指令
2.VNode的分类
VNode可以理解为VueVirtual Dom的一个基类,通过VNode构造函数生成的VNnode实例可为如下几类:
- EmptyVNode: 没有内容的注释节点