From 5e4df55bced8676dbb088bba209fada0d13ff284 Mon Sep 17 00:00:00 2001 From: linzhe141 <1572213544@qq.com> Date: Wed, 12 Nov 2025 15:16:23 +0800 Subject: [PATCH 1/3] fix(suspense): defer clearing fallback vnode reference to should unmount active branch first --- .../runtime-core/src/components/Suspense.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/runtime-core/src/components/Suspense.ts b/packages/runtime-core/src/components/Suspense.ts index d14e96be3d0..4731e939409 100644 --- a/packages/runtime-core/src/components/Suspense.ts +++ b/packages/runtime-core/src/components/Suspense.ts @@ -20,6 +20,7 @@ import { type RendererInternals, type RendererNode, type SetupRenderEffectFn, + queuePostRenderEffect, } from '../renderer' import { queuePostFlushCb } from '../scheduler' import { filterSingleRoot, updateHOCHostEl } from '../componentRenderUtils' @@ -553,9 +554,11 @@ function createSuspenseBoundary( ) queuePostFlushCb(effects) // clear el reference from fallback vnode to allow GC after transition - if (isInFallback && vnode.ssFallback) { - vnode.ssFallback.el = null - } + queuePostRenderEffect(() => { + if (isInFallback && vnode.ssFallback) { + vnode.ssFallback.el = null + } + }, suspense) } } } @@ -577,9 +580,11 @@ function createSuspenseBoundary( unmount(activeBranch, parentComponent, suspense, true) // clear el reference from fallback vnode to allow GC // only clear immediately if there's no delayed transition - if (!delayEnter && isInFallback && vnode.ssFallback) { - vnode.ssFallback.el = null - } + queuePostRenderEffect(() => { + if (!delayEnter && isInFallback && vnode.ssFallback) { + vnode.ssFallback.el = null + } + }, suspense) } if (!delayEnter) { // move content from off-dom container to actual container From f6ec7757cd50fff9c325dd192d14a616f24b4a24 Mon Sep 17 00:00:00 2001 From: linzhe141 <1572213544@qq.com> Date: Wed, 12 Nov 2025 17:40:18 +0800 Subject: [PATCH 2/3] chore: add unit test --- .../__tests__/components/Suspense.spec.ts | 36 +++++++++++++++++++ .../runtime-core/src/components/Suspense.ts | 8 ++--- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/runtime-core/__tests__/components/Suspense.spec.ts b/packages/runtime-core/__tests__/components/Suspense.spec.ts index c6683d6a257..4e8da3288f1 100644 --- a/packages/runtime-core/__tests__/components/Suspense.spec.ts +++ b/packages/runtime-core/__tests__/components/Suspense.spec.ts @@ -24,6 +24,7 @@ import { shallowRef, watch, watchEffect, + withDirectives, } from '@vue/runtime-test' import { computed, createApp, defineComponent, inject, provide } from 'vue' import type { RawSlots } from 'packages/runtime-core/src/componentSlots' @@ -2358,5 +2359,40 @@ describe('Suspense', () => { `