export function shouldUpdateComponent(
prevVNode: VNode,
- nextVNode: VNode
+ nextVNode: VNode,
+ optimized?: boolean
): boolean {
const { props: prevProps, children: prevChildren } = prevVNode
const { props: nextProps, children: nextChildren, patchFlag } = nextVNode
}
}
}
- } else {
+ } else if (!optimized) {
// this path is only taken by manually written render functions
// so presence of any children leads to a forced update
if (prevChildren != null || nextChildren != null) {
// TODO warn invalid node type
debugger
}
- processComponent(n1, n2, container, anchor)
+ processComponent(n1, n2, container, anchor, optimized)
}
break
}
n1: VNode | null,
n2: VNode,
container: HostNode,
- anchor?: HostNode
+ anchor?: HostNode,
+ optimized?: boolean
) {
if (n1 == null) {
mountComponent(n2, container, anchor)
} else {
const instance = (n2.component = n1.component) as ComponentInstance
- if (shouldUpdateComponent(n1, n2)) {
+ if (shouldUpdateComponent(n1, n2, optimized)) {
instance.next = n2
instance.update()
} else {
+ n2.component = n1.component
n2.el = n1.el
}
}
-import { isArray, isFunction, isString, EMPTY_ARR } from '@vue/shared'
+import { isArray, isFunction, isString, isObject, EMPTY_ARR } from '@vue/shared'
import { ComponentInstance } from './component'
import { HostNode } from './createRenderer'
import { RawSlots } from './componentSlots'
export function createVNode(
type: VNodeTypes,
- props: { [key: string]: any } | null = null,
+ props: { [key: string]: any } | null | 0 = null,
children: any = null,
patchFlag: number | null = null,
dynamicProps: string[] | null = null
): VNode {
const vnode: VNode = {
type,
- props,
+ props: props || null,
key: props && props.key,
children: normalizeChildren(children),
component: null,
dynamicChildren: null
}
// presence of a patch flag indicates this node is dynamic
- if (shouldTrack && patchFlag != null) {
+ // component nodes also should always be tracked, because even if the
+ // component doesn't need to update, it needs to persist the instance on to
+ // the next vnode so that it can be properly unmounted later.
+ if (
+ shouldTrack &&
+ (patchFlag != null || isObject(type) || isFunction(type))
+ ) {
trackDynamicNode(vnode)
}
return vnode