From 261a2ebd8d797010b1733f1011ef9389d3e18798 Mon Sep 17 00:00:00 2001 From: Rairn <958414905@qq.com> Date: Wed, 7 Dec 2022 16:08:34 +0800 Subject: [PATCH] fix(keep-alive): invoke initial activated hook for async components's child component (#7276) --- .../__tests__/components/KeepAlive.spec.ts | 36 +++++++++++++++++++ .../runtime-core/src/components/KeepAlive.ts | 10 +++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/components/KeepAlive.spec.ts b/packages/runtime-core/__tests__/components/KeepAlive.spec.ts index 344fba156c3..dd1c14f4be5 100644 --- a/packages/runtime-core/__tests__/components/KeepAlive.spec.ts +++ b/packages/runtime-core/__tests__/components/KeepAlive.spec.ts @@ -883,6 +883,42 @@ describe('KeepAlive', () => { expect(serializeInner(root)).toBe('

1

') }) + // #7276 + test('should invoke onActivated of child on initial mount', async () => { + let parentCount = 0 + let childCount = 0 + const Child = defineComponent({ + name: 'Child', + setup() { + onActivated(() => { + childCount++ + }) + return () => 'child' + } + }) + const Parent = defineComponent({ + setup() { + onActivated(() => { + parentCount++ + }) + return () => h(Child) + } + }) + const AsyncComp = defineAsyncComponent(() => Promise.resolve(Parent)) + + const App = { + render: () => { + return h(KeepAlive, null, () => h(AsyncComp)) + } + } + + render(h(App), root) + await timeout() + expect(serializeInner(root)).toBe('child') + expect(parentCount).toBe(1) + expect(childCount).toBe(1) + }) + // #4976 test('handle error in async onActivated', async () => { const err = new Error('foo') diff --git a/packages/runtime-core/src/components/KeepAlive.ts b/packages/runtime-core/src/components/KeepAlive.ts index d5813f90e09..3bc58edfe6a 100644 --- a/packages/runtime-core/src/components/KeepAlive.ts +++ b/packages/runtime-core/src/components/KeepAlive.ts @@ -402,10 +402,18 @@ function registerKeepAliveHook( // arrays. if (target) { let current = target.parent + let child = target while (current && current.parent) { if (isKeepAlive(current.parent.vnode)) { - injectToKeepAliveRoot(wrappedHook, type, target, current) + injectToKeepAliveRoot( + wrappedHook, + type, + target, + // #7276 + isAsyncWrapper(current) ? child : current + ) } + child = current current = current.parent } }