function mount(
vnode: VNode,
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
const { flags } = vnode
if (flags & VNodeFlags.ELEMENT) {
- mountElement(vnode, container, parentComponent, isSVG, endNode)
+ mountElement(vnode, container, contextVNode, isSVG, endNode)
} else if (flags & VNodeFlags.COMPONENT_STATEFUL) {
- mountStatefulComponent(vnode, container, parentComponent, isSVG, endNode)
+ mountStatefulComponent(vnode, container, contextVNode, isSVG, endNode)
} else if (flags & VNodeFlags.COMPONENT_FUNCTIONAL) {
- mountFunctionalComponent(
- vnode,
- container,
- parentComponent,
- isSVG,
- endNode
- )
+ mountFunctionalComponent(vnode, container, contextVNode, isSVG, endNode)
} else if (flags & VNodeFlags.TEXT) {
mountText(vnode, container, endNode)
} else if (flags & VNodeFlags.FRAGMENT) {
- mountFragment(vnode, container, parentComponent, isSVG, endNode)
+ mountFragment(vnode, container, contextVNode, isSVG, endNode)
} else if (flags & VNodeFlags.PORTAL) {
- mountPortal(vnode, container, parentComponent)
+ mountPortal(vnode, container, contextVNode)
}
}
function mountArrayChildren(
children: VNode[],
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
if (child.el) {
children[i] = child = cloneVNode(child)
}
- mount(children[i], container, parentComponent, isSVG, endNode)
+ mount(children[i], container, contextVNode, isSVG, endNode)
}
}
function mountElement(
vnode: VNode,
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
if (childFlags !== ChildrenFlags.NO_CHILDREN) {
const hasSVGChildren = isSVG && tag !== 'foreignObject'
if (childFlags & ChildrenFlags.SINGLE_VNODE) {
- mount(children as VNode, el, parentComponent, hasSVGChildren, endNode)
+ mount(children as VNode, el, contextVNode, hasSVGChildren, endNode)
} else if (childFlags & ChildrenFlags.MULTIPLE_VNODES) {
mountArrayChildren(
children as VNode[],
el,
- parentComponent,
+ contextVNode,
hasSVGChildren,
endNode
)
function mountStatefulComponent(
vnode: VNode,
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
+ vnode.contextVNode = contextVNode
if (vnode.flags & VNodeFlags.COMPONENT_STATEFUL_KEPT_ALIVE) {
// kept-alive
activateComponentInstance(vnode)
vnode,
vnode.tag as ComponentClass,
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
function mountFunctionalComponent(
vnode: VNode,
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
+ vnode.contextVNode = contextVNode
const { tag, data, slots } = vnode
const render = tag as FunctionalComponent
const { props, attrs } = resolveProps(data, render.props)
render(props, slots || EMPTY_OBJ, attrs || EMPTY_OBJ),
vnode
))
- mount(subTree, container, parentComponent, isSVG, endNode)
+ mount(subTree, container, vnode as MountedVNode, isSVG, endNode)
vnode.el = subTree.el as RenderNode
}
function mountFragment(
vnode: VNode,
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
const { children, childFlags } = vnode
switch (childFlags) {
case ChildrenFlags.SINGLE_VNODE:
- mount(children as VNode, container, parentComponent, isSVG, endNode)
+ mount(children as VNode, container, contextVNode, isSVG, endNode)
vnode.el = (children as MountedVNode).el
break
case ChildrenFlags.NO_CHILDREN:
mountArrayChildren(
children as VNode[],
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
function mountPortal(
vnode: VNode,
container: RenderNode | null,
- parentComponent: ComponentInstance | null
+ contextVNode: MountedVNode | null
) {
const { tag, children, childFlags, ref } = vnode
const target = typeof tag === 'string' ? platformQuerySelector(tag) : tag
}
if (childFlags & ChildrenFlags.SINGLE_VNODE) {
- mount(
- children as VNode,
- target as RenderNode,
- parentComponent,
- false,
- null
- )
+ mount(children as VNode, target as RenderNode, contextVNode, false, null)
} else if (childFlags & ChildrenFlags.MULTIPLE_VNODES) {
mountArrayChildren(
children as VNode[],
target as RenderNode,
- parentComponent,
+ contextVNode,
false,
null
)
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean
) {
const nextFlags = nextVNode.flags
const prevFlags = prevVNode.flags
if (prevFlags !== nextFlags) {
- replaceVNode(prevVNode, nextVNode, container, parentComponent, isSVG)
+ replaceVNode(prevVNode, nextVNode, container, contextVNode, isSVG)
} else if (nextFlags & VNodeFlags.ELEMENT) {
- patchElement(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patchElement(prevVNode, nextVNode, container, contextVNode, isSVG)
} else if (nextFlags & VNodeFlags.COMPONENT) {
- patchComponent(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patchComponent(prevVNode, nextVNode, container, contextVNode, isSVG)
} else if (nextFlags & VNodeFlags.TEXT) {
patchText(prevVNode, nextVNode)
} else if (nextFlags & VNodeFlags.FRAGMENT) {
- patchFragment(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patchFragment(prevVNode, nextVNode, container, contextVNode, isSVG)
} else if (nextFlags & VNodeFlags.PORTAL) {
- patchPortal(prevVNode, nextVNode, parentComponent)
+ patchPortal(prevVNode, nextVNode, contextVNode)
}
}
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean
) {
const { flags, tag } = nextVNode
isSVG = isSVG || (flags & VNodeFlags.ELEMENT_SVG) > 0
if (prevVNode.tag !== tag) {
- replaceVNode(prevVNode, nextVNode, container, parentComponent, isSVG)
+ replaceVNode(prevVNode, nextVNode, container, contextVNode, isSVG)
return
}
prevVNode.children,
nextVNode.children,
el,
- parentComponent,
+ contextVNode,
isSVG && nextVNode.tag !== 'foreignObject',
null
)
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean
) {
+ nextVNode.contextVNode = contextVNode
const { tag, flags } = nextVNode
if (tag !== prevVNode.tag) {
- replaceVNode(prevVNode, nextVNode, container, parentComponent, isSVG)
+ replaceVNode(prevVNode, nextVNode, container, contextVNode, isSVG)
} else if (flags & VNodeFlags.COMPONENT_STATEFUL) {
patchStatefulComponent(prevVNode, nextVNode)
} else {
prevVNode,
nextVNode,
container,
- parentComponent,
+ contextVNode,
isSVG
)
}
if (shouldForceUpdate) {
instance.$forceUpdate()
} else if (instance.$vnode.flags & VNodeFlags.COMPONENT) {
- instance.$vnode.parentVNode = nextVNode
+ instance.$vnode.contextVNode = nextVNode
}
nextVNode.el = instance.$vnode.el
}
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean
) {
// functional component tree is stored on the vnode as `children`
render(props, nextSlots || EMPTY_OBJ, attrs || EMPTY_OBJ),
nextVNode
))
- patch(prevTree, nextTree, container, parentComponent, isSVG)
+ patch(prevTree, nextTree, container, nextVNode as MountedVNode, isSVG)
nextVNode.el = nextTree.el
} else if (prevTree.flags & VNodeFlags.COMPONENT) {
// functional component returned another component
- prevTree.parentVNode = nextVNode
+ prevTree.contextVNode = nextVNode
}
}
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean
) {
// determine the tail node of the previous fragment,
prevVNode.children,
children,
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
function patchPortal(
prevVNode: MountedVNode,
nextVNode: VNode,
- parentComponent: ComponentInstance | null
+ contextVNode: MountedVNode | null
) {
const prevContainer = prevVNode.tag as RenderNode
const nextContainer = nextVNode.tag as RenderNode
prevVNode.children,
nextChildren,
prevContainer,
- parentComponent,
+ contextVNode,
false,
null
)
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean
) {
const refNode = platformNextSibling(getVNodeLastEl(prevVNode))
removeVNode(prevVNode, container)
- mount(nextVNode, container, parentComponent, isSVG, refNode)
+ mount(nextVNode, container, contextVNode, isSVG, refNode)
}
function patchChildren(
prevChildren: VNodeChildren,
nextChildren: VNodeChildren,
container: RenderNode,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
prevChildren as MountedVNode,
nextChildren as VNode,
container,
- parentComponent,
+ contextVNode,
isSVG
)
break
mountArrayChildren(
nextChildren as VNode[],
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
mount(
nextChildren as VNode,
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
mountArrayChildren(
nextChildren as VNode[],
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
// MULTIPLE_CHILDREN
if (nextChildFlags === ChildrenFlags.SINGLE_VNODE) {
removeChildren(prevChildren as MountedVNode[], container, endNode)
- mount(
- nextChildren as VNode,
- container,
- parentComponent,
- isSVG,
- endNode
- )
+ mount(nextChildren as VNode, container, contextVNode, isSVG, endNode)
} else if (nextChildFlags === ChildrenFlags.NO_CHILDREN) {
removeChildren(prevChildren as MountedVNode[], container, endNode)
} else {
mountArrayChildren(
nextChildren as VNode[],
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
container,
prevLength,
nextLength,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
container,
prevLength,
nextLength,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
container: RenderNode,
prevLength: number,
nextLength: number,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
if (nextChild.el) {
nextChildren[i] = nextChild = cloneVNode(nextChild)
}
- patch(prevChild, nextChild, container, parentComponent, isSVG)
+ patch(prevChild, nextChild, container, contextVNode, isSVG)
prevChildren[i] = nextChild as MountedVNode
}
if (prevLength < nextLength) {
if (nextChild.el) {
nextChildren[i] = nextChild = cloneVNode(nextChild)
}
- mount(nextChild, container, parentComponent, isSVG, endNode)
+ mount(nextChild, container, contextVNode, isSVG, endNode)
}
} else if (prevLength > nextLength) {
for (i = commonLength; i < prevLength; i++) {
container: RenderNode,
prevLength: number,
nextLength: number,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
) {
if (nextVNode.el) {
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
}
- patch(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patch(prevVNode, nextVNode, container, contextVNode, isSVG)
prevChildren[j] = nextVNode as MountedVNode
j++
if (j > prevEnd || j > nextEnd) {
if (nextVNode.el) {
nextChildren[nextEnd] = nextVNode = cloneVNode(nextVNode)
}
- patch(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patch(prevVNode, nextVNode, container, contextVNode, isSVG)
prevChildren[prevEnd] = nextVNode as MountedVNode
prevEnd--
nextEnd--
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
}
j++
- mount(nextVNode, container, parentComponent, isSVG, nextNode)
+ mount(nextVNode, container, contextVNode, isSVG, nextNode)
}
}
} else if (j > nextEnd) {
if (nextVNode.el) {
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
}
- patch(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patch(prevVNode, nextVNode, container, contextVNode, isSVG)
patched++
break
}
if (nextVNode.el) {
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
}
- patch(prevVNode, nextVNode, container, parentComponent, isSVG)
+ patch(prevVNode, nextVNode, container, contextVNode, isSVG)
patched++
} else if (!canRemoveWholeContent) {
removeVNode(prevVNode, container)
mountArrayChildren(
nextChildren,
container,
- parentComponent,
+ contextVNode,
isSVG,
endNode
)
mount(
nextVNode,
container,
- parentComponent,
+ contextVNode,
isSVG,
nextPos < nextLength ? nextChildren[nextPos].el : endNode
)
mount(
nextVNode,
container,
- parentComponent,
+ contextVNode,
isSVG,
nextPos < nextLength ? nextChildren[nextPos].el : endNode
)
// Component lifecycle -------------------------------------------------------
function mountComponentInstance(
- parentVNode: VNode,
+ vnode: VNode,
Component: ComponentClass,
container: RenderNode | null,
- parentComponent: ComponentInstance | null,
+ contextVNode: MountedVNode | null,
isSVG: boolean,
endNode: RenderNode | null
): RenderNode {
// a vnode may already have an instance if this is a compat call with
// new Vue()
const instance =
- (__COMPAT__ && (parentVNode.children as ComponentInstance)) ||
- createComponentInstance(parentVNode, Component, parentComponent)
+ (__COMPAT__ && (vnode.children as ComponentInstance)) ||
+ createComponentInstance(vnode, Component, contextVNode)
// inject platform-specific unmount to keep-alive container
if ((Component as any)[KeepAliveSymbol] === true) {
} else {
// this will be executed synchronously right here
instance.$vnode = renderInstanceRoot(instance) as MountedVNode
- mount(instance.$vnode, container, instance, isSVG, endNode)
- parentVNode.el = instance.$vnode.el
+ mount(
+ instance.$vnode,
+ container,
+ vnode as MountedVNode,
+ isSVG,
+ endNode
+ )
+ vnode.el = instance.$vnode.el
if (__DEV__) {
// expose __vue__ for devtools
- ;(parentVNode.el as any).__vue__ = instance
+ ;(vnode.el as any).__vue__ = instance
}
instance._mounted = true
- mountComponentInstanceCallbacks(instance, parentVNode.ref)
+ mountComponentInstanceCallbacks(instance, vnode.ref)
}
},
{
}
)
- return parentVNode.el as RenderNode
+ return vnode.el as RenderNode
}
function mountComponentInstanceCallbacks(
ref: Ref | null
) {
if (ref) {
- mountRef(ref, instance)
+ mountRef(ref, instance.$proxy)
}
if (instance.mounted) {
lifecycleHooks.push(() => {
instance
) as MountedVNode)
const container = platformParentNode(prevVNode.el) as RenderNode
- patch(prevVNode, nextVNode, container, instance, isSVG)
+ patch(
+ prevVNode,
+ nextVNode,
+ container,
+ instance.$parentVNode as MountedVNode,
+ isSVG
+ )
const el = nextVNode.el as RenderNode
if (__DEV__) {
;(el as any).__vue__ = instance
}
- // recursively update parentVNode el for nested HOCs
+ // recursively update contextVNode el for nested HOCs
if ((nextVNode.flags & VNodeFlags.PORTAL) === 0) {
let vnode = instance.$parentVNode
while (vnode !== null) {
if ((vnode.flags & VNodeFlags.COMPONENT) > 0) {
vnode.el = el
}
- vnode = vnode.parentVNode
+ vnode = vnode.contextVNode
}
}
// API -----------------------------------------------------------------------
- function render(vnode: VNode | null, container: any) {
+ function render(
+ vnode: VNode | null,
+ container: any
+ ): ComponentInstance | null {
const prevVNode = container.vnode
if (vnode && vnode.el) {
vnode = cloneVNode(vnode)