From: Evan You Date: Wed, 11 Sep 2019 14:22:10 +0000 (-0400) Subject: fix: patching a component with pending async setup should update its props and slots X-Git-Tag: v3.0.0-alpha.0~784 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dff4e7cd447dcb2168c14bbed62d3ba1966596c8;p=thirdparty%2Fvuejs%2Fcore.git fix: patching a component with pending async setup should update its props and slots --- diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index 302b6838b1..7fb289ce6c 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -844,19 +844,28 @@ export function createRenderer< const instance = (n2.component = n1.component) as ComponentInternalInstance - // async still pending - if ( - __FEATURE_SUSPENSE__ && - instance.asyncDep && - !instance.asyncResolved - ) { - return - } - if (shouldUpdateComponent(n1, n2, optimized)) { - // normal update - instance.next = n2 - instance.update() + if ( + __FEATURE_SUSPENSE__ && + instance.asyncDep && + !instance.asyncResolved + ) { + // async & still pending - just update props and slots + // since the component's reactive effect for render isn't set-up yet + if (__DEV__) { + pushWarningContext(n2) + } + updateComponentPropsAndSlots(instance, n2) + if (__DEV__) { + popWarningContext() + } + return + } else { + // normal update + instance.next = n2 + // instance.update is the reactive effect runner. + instance.update() + } } else { // no update needed. just copy over properties n2.component = n1.component @@ -981,12 +990,7 @@ export function createRenderer< } if (next !== null) { - // update from parent - next.component = instance - instance.vnode = next - instance.next = null - resolveProps(instance, next.props, (initialVNode.type as any).props) - resolveSlots(instance, next.children) + updateComponentPropsAndSlots(instance, next) } const prevTree = instance.subTree const nextTree = (instance.subTree = renderComponentRoot(instance)) @@ -1030,6 +1034,17 @@ export function createRenderer< }, __DEV__ ? createDevEffectOptions(instance) : prodEffectOptions) } + function updateComponentPropsAndSlots( + instance: ComponentInternalInstance, + nextVNode: HostVNode + ) { + nextVNode.component = instance + instance.vnode = nextVNode + instance.next = null + resolveProps(instance, nextVNode.props, (nextVNode.type as any).props) + resolveSlots(instance, nextVNode.children) + } + function updateHOCHostEl( { vnode, parent }: ComponentInternalInstance, el: HostNode @@ -1624,11 +1639,7 @@ export function createRenderer< function getSequence(arr: number[]): number[] { const p = arr.slice() const result = [0] - let i - let j - let u - let v - let c + let i, j, u, v, c const len = arr.length for (i = 0; i < len; i++) { const arrI = arr[i]