]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(Transition): handle leave immediatily done in out-in mode edison/fix/TransitionOnLeave 11824/head
authordaiwei <daiwei521@126.com>
Thu, 5 Sep 2024 09:22:55 +0000 (17:22 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 5 Sep 2024 09:22:55 +0000 (17:22 +0800)
packages/runtime-core/src/components/BaseTransition.ts
packages/vue/__tests__/e2e/Transition.spec.ts

index 568a6382bfec33d90c2c2e48c4a23e16dc052e25..6d61dd0507e1b932a17e795e1ed1f965164517ad 100644 (file)
@@ -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<T = () => 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
           }
index 8cdda4dc63e2b02cbc782592a5557ec99c838dcd..e606a74bdb3aad7c53ad8d24a533ddb1682e63e4 100644 (file)
@@ -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: `
+              <div id="container">
+                <transition mode="out-in" @leave="onLeave">
+                  <div v-if="toggle">True</div>
+                  <div v-else>False</div>
+                </transition>
+              </div>
+              <button id="toggleBtn" @click="click">button</button>
+            `,
+            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('<div>True</div>')
+
+        await click('#toggleBtn')
+        await transitionFinish()
+        expect(onLeaveSpy).toBeCalled()
+        expect(await html('#container')).toBe('<div class="">False</div>')
+      },
+      E2E_TIMEOUT,
+    )
+
     test(
       'css: false',
       async () => {