From 9b6ecdeace96a6aa1fb825335fcfd66f9f49b837 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 19 Feb 2025 22:01:35 +0800 Subject: [PATCH] fix(runtime-core): handle KeepAlive children unmount when wrapped in stable v-for --- .../__tests__/rendererOptimizedMode.spec.ts | 49 +++++++++++++++++++ packages/runtime-core/src/renderer.ts | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts b/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts index 958c127480..5496cd8305 100644 --- a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts +++ b/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts @@ -1,10 +1,12 @@ import { Fragment, type FunctionalComponent, + KeepAlive, type SetupContext, Teleport, type TestElement, type VNode, + computed, createApp, createBlock, createCommentVNode, @@ -1294,4 +1296,51 @@ describe('renderer: optimized mode', () => { expect(inner(root)).toBe('') expect(beforeUnmountSpy).toHaveBeenCalledTimes(1) }) + + //#12914 + test('unmount KeepAlive children when wrapped in v-for with stable fragment', async () => { + const CompA = { + setup() { + return () => h('span', 'CompA') + }, + } + const CompB = { + setup() { + return () => h('span', 'CompB') + }, + } + + const toggle = ref(true) + const view = computed(() => { + return toggle.value ? CompA : CompB + }) + + const app = createApp({ + render() { + return ( + openBlock(), + createElementBlock( + Fragment, + null, + renderList(1, () => { + return createVNode( + KeepAlive, + null, + [(openBlock(), createBlock(view.value))], + 1024 /* DYNAMIC_SLOTS */, + ) + }), + 64 /* STABLE_FRAGMENT */, + ) + ) + }, + }) + + app.mount(root) + expect(inner(root)).toBe('CompA') + + toggle.value = false + await nextTick() + expect(inner(root)).toBe('CompB') + }) }) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 05c4ac345e..ccf99f6b4a 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -2107,7 +2107,7 @@ function baseCreateRenderer( } if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) { - ;(parentComponent!.ctx as KeepAliveContext).deactivate(vnode) + ;(vnode.component!.parent!.ctx as KeepAliveContext).deactivate(vnode) return } -- 2.47.2