diff --git a/packages/runtime-core/src/components/Suspense.ts b/packages/runtime-core/src/components/Suspense.ts index 0fa07d9beec..3640733d734 100644 --- a/packages/runtime-core/src/components/Suspense.ts +++ b/packages/runtime-core/src/components/Suspense.ts @@ -491,10 +491,12 @@ function createSuspenseBoundary( container } = suspense + // if there's a transition happening we need to wait it to finish. + let delayEnter: boolean | null = false if (suspense.isHydrating) { suspense.isHydrating = false } else if (!resume) { - const delayEnter = + delayEnter = activeBranch && pendingBranch!.transition && pendingBranch!.transition.mode === 'out-in' @@ -502,6 +504,7 @@ function createSuspenseBoundary( activeBranch!.transition!.afterLeave = () => { if (pendingId === suspense.pendingId) { move(pendingBranch!, container, anchor, MoveType.ENTER) + queuePostFlushCb(effects) } } } @@ -538,8 +541,8 @@ function createSuspenseBoundary( } parent = parent.parent } - // no pending parent suspense, flush all jobs - if (!hasUnresolvedAncestor) { + // no pending parent suspense nor transition, flush all jobs + if (!hasUnresolvedAncestor && !delayEnter) { queuePostFlushCb(effects) } suspense.effects = [] diff --git a/packages/vue/__tests__/e2e/Transition.spec.ts b/packages/vue/__tests__/e2e/Transition.spec.ts index 326eaa57e3d..38fdf53cf4f 100644 --- a/packages/vue/__tests__/e2e/Transition.spec.ts +++ b/packages/vue/__tests__/e2e/Transition.spec.ts @@ -1498,6 +1498,94 @@ describe('e2e: Transition', () => { }, E2E_TIMEOUT ) + + // #5844 + test('children mount should be called after html changes', async () => { + const fooMountSpy = vi.fn() + const barMountSpy = vi.fn() + + await page().exposeFunction('fooMountSpy', fooMountSpy) + await page().exposeFunction('barMountSpy', barMountSpy) + + await page().evaluate(() => { + const { fooMountSpy, barMountSpy } = window as any + const { createApp, ref, h, onMounted } = (window as any).Vue + createApp({ + template: ` +