VNode的类型
在VUE中通过属性之间不同的搭配,VNode类可以描述出各种类型的真实DOM节点,总共有以下几种
- 注释节点:注释节点描述起来相对简单,只需要两个属性
//创建注释节点
export const createEmptyVNode = (text: string = "") => {
const node = new VNode()
node.text = etxt
node.isComment = true
retrun node
}
上方代码中text属性表示具体的注释信息,isComment是一个标志,用来标识一个几点是否是注释节点
- 文本节点:注释节点描述起来更简单,只需要一个属性,那就是text属性,用来表示具体的文本信息
//创建文本节点
export const createTextVNode = (val: string | number) => {
retrun new VNode(undefined,undefined,undefined,String(val))
}
- 克隆节点:克隆节点就是把一个已经存在的节点复制一份出来,他主要是为了做模板编译优化时使用。
//创建克隆节点
export function cloneVNode(vnode: VNode): VNode {
const cloned = new VNode(
vnode.tag,
vnode.data,
vnode.children,
vnode.text,
vnode.elm,
vnode.context,
vnode.componentOptions,
vnode.asyncFactory
)
cloned.ns = vnode.ns
cloned.isStatic = vnode.isStatic
cloned.key = vnode.key
cloned.isComment = vnode.isComment
cloned.fnContext = vnode.fnContext
cloned.fnOptions = vnode.fnOptions
cloned.fnScopeId = vnode.fnScopeId
cloned.asyncMeta = vnode.asyncMeta
cloned.isCloned = true
return cloned
}
从上方代码可以看出,克隆节点就是把已有节点的属性全部复制到新节点中,而现有节点和新克隆得到的节点之间唯一不同的就是克隆得到的节点isCloned为true
-
元素节点:相比之下,元素节点更贴近于我们通常看到的真实DOM节点,他有描述节点标签名词tag属性,描述节点属性如class等的data属性,有描述子节点信息的children属性等。由于元素节点所包含的情况相比而言比较复杂,源码中没有像前三种节点一样直接写死,在这就不过多说明了。
-
组件节点:组件节点除了有元素节点具有的属性之外,它还有两个特有的属性:
- componentOptions: 组件节点的options选项,如组件的props等
- componentInstance:当前组件节点对应的Vue实例
-
函数式组件节点:函数式组件节点相较于组件节点,他又有两个特有的属性
- fnContext:函数式组件对应的Vue实例
- fnOptions:组件的option选项
Vnode的作用
我们在视图渲染之前,把写好的template模板先编译成VNode并缓存下来,等到数据发生变化页面需要重新渲染的时候,我们把数据发生变化后生成的VNode与前一次缓存下来的VNode进行对比,找出差异,然后有差异的VNode对应的真实DOM节点就是需要重新渲染的节点,最后根据有差异的VNode创建出真实的DOM节点再插入到视图中,最终完成一次试图更新。