diff --git a/packages/runtime-core/src/components/BaseTransition.ts b/packages/runtime-core/src/components/BaseTransition.ts index 568a6382bfe..6d61dd0507e 100644 --- a/packages/runtime-core/src/components/BaseTransition.ts +++ b/packages/runtime-core/src/components/BaseTransition.ts @@ -20,7 +20,7 @@ import { PatchFlags, ShapeFlags, isArray, isFunction } from '@vue/shared' import { onBeforeUnmount, onMounted } from '../apiLifecycle' import { isTeleport } from './Teleport' import type { RendererElement } from '../renderer' -import { SchedulerJobFlags } from '../scheduler' +import { SchedulerJobFlags, queueJob } from '../scheduler' type Hook void> = T | T[] @@ -225,7 +225,7 @@ const BaseTransitionImpl: ComponentOptions = { // #6835 // it also needs to be updated when active is undefined if (!(instance.job.flags! & SchedulerJobFlags.DISPOSED)) { - instance.update() + queueJob(instance.update) } delete leavingHooks.afterLeave } diff --git a/packages/vue/__tests__/e2e/Transition.spec.ts b/packages/vue/__tests__/e2e/Transition.spec.ts index 8cdda4dc63e..e606a74bdb3 100644 --- a/packages/vue/__tests__/e2e/Transition.spec.ts +++ b/packages/vue/__tests__/e2e/Transition.spec.ts @@ -767,6 +767,52 @@ describe('e2e: Transition', () => { E2E_TIMEOUT, ) + test( + 'onLeave event immediately done (out-in mode)', + async () => { + const onLeaveSpy = vi.fn() + await page().exposeFunction('onLeaveSpy', onLeaveSpy) + + await page().evaluate(async () => { + const { onLeaveSpy } = window as any + const { createApp, ref } = (window as any).Vue + createApp({ + template: ` +
+ +
True
+
False
+
+
+ + `, + setup: () => { + const toggle = ref(true) + function onLeave(el: Element, done: Function) { + onLeaveSpy() + // immediately done + done() + } + const click = () => (toggle.value = !toggle.value) + return { + toggle, + click, + onLeave, + } + }, + }).mount('#app') + }) + + expect(await html('#container')).toBe('
True
') + + await click('#toggleBtn') + await transitionFinish() + expect(onLeaveSpy).toBeCalled() + expect(await html('#container')).toBe('
False
') + }, + E2E_TIMEOUT, + ) + test( 'css: false', async () => {