Vue源码探究之虚拟节点的实现

2020-06-14 06:07:13易采站长站整理

fnScopeId: ?string; // functional scope id support

// 构造函数,参数均可选,与上面定义对应
constructor (
tag?: string,
data?: VNodeData,
children?: ?Array<VNode>,
text?: string,
elm?: Node,
context?: Component,
componentOptions?: VNodeComponentOptions,
asyncFactory?: Function
) {
// 实例初始化赋值
this.tag = tag
this.data = data
this.children = children
this.text = text
this.elm = elm
this.ns = undefined
this.context = context
this.fnContext = undefined
this.fnOptions = undefined
this.fnScopeId = undefined
this.key = data && data.key
this.componentOptions = componentOptions
this.componentInstance = undefined
this.parent = undefined
this.raw = false
this.isStatic = false
this.isRootInsert = true
this.isComment = false
this.isCloned = false
this.isOnce = false
this.asyncFactory = asyncFactory
this.asyncMeta = undefined
this.isAsyncPlaceholder = false
}

// 定义child属性的取值器
// 已弃用:用于向后compat的componentInstance的别名
// DEPRECATED: alias for componentInstance for backwards compat.
/* istanbul ignore next */
get child (): Component | void {
return this.componentInstance
}
}

// 定义并导出createEmptyVNode函数,创建空虚拟节点
export const createEmptyVNode = (text: string = '') => {
// 实例化虚拟节点
const node = new VNode()
// 设置节点文字为空,并设置为注释节点
node.text = text
node.isComment = true
// 返回节点
return node
}

// 定义并导出createTextVNode函数,创建文字虚拟节点
export function createTextVNode (val: string | number) {
// 置空实例初始化的标签名,数据,子节点属性,只传入文字
return new VNode(undefined, undefined, undefined, String(val))
}

// 优化浅拷贝
// 用于静态节点和插槽节点,因为它们可以在多个渲染中重用,
// 当DOM操作依赖于它们的elm引用时,克隆它们可以避免错误
// optimized shallow clone
// used for static nodes and slot nodes because they may be reused across
// multiple renders, cloning them avoids errors when DOM manipulations rely
// on their elm reference.
// 定义并导出cloneVNode函数,拷贝节点
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