From 05556eacb2a15fb139df79f98698ac252d4f0ff4 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 1 Jun 2019 02:14:49 +0800 Subject: [PATCH] wip: always track component nodes --- packages/runtime-core/src/component.ts | 5 +++-- packages/runtime-core/src/createRenderer.ts | 8 +++++--- packages/runtime-core/src/index.ts | 8 +++----- packages/runtime-core/src/vnode.ts | 14 ++++++++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 5ae92c9f..d3450081 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -163,7 +163,8 @@ export function renderComponentRoot(instance: ComponentInstance): VNode { 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 @@ -185,7 +186,7 @@ export function shouldUpdateComponent( } } } - } 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) { diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index fa7a6175..636af115 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -139,7 +139,7 @@ export function createRenderer(options: RendererOptions) { // TODO warn invalid node type debugger } - processComponent(n1, n2, container, anchor) + processComponent(n1, n2, container, anchor, optimized) } break } @@ -426,16 +426,18 @@ export function createRenderer(options: RendererOptions) { 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 } } diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index f7ce3941..cc12c13e 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -3,15 +3,13 @@ export { openBlock, createBlock, createVNode, + Text, + Empty, Fragment, Portal } from './vnode' -export { - ComponentOptions, - FunctionalComponent, - createComponent -} from './component' +export { FunctionalComponent, createComponent } from './component' export { Slot, Slots } from './componentSlots' diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index d6f9e3c2..d9fc82fb 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -1,4 +1,4 @@ -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' @@ -85,14 +85,14 @@ export function createBlock( 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, @@ -104,7 +104,13 @@ export function createVNode( 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