]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): Suspense get anchor properly in Transition (#9309)
authoredison <daiwei521@126.com>
Mon, 4 Dec 2023 08:41:55 +0000 (16:41 +0800)
committerGitHub <noreply@github.com>
Mon, 4 Dec 2023 08:41:55 +0000 (16:41 +0800)
close #8105

packages/runtime-core/src/components/Suspense.ts
packages/vue/__tests__/e2e/Transition.spec.ts

index ddf21dd2ed474afcaee92c724a4b80d4a658fadb..5e5521b09be535ea28d6bdaaf857766e2cc9d63c 100644 (file)
@@ -504,7 +504,12 @@ function createSuspenseBoundary(
         if (delayEnter) {
           activeBranch!.transition!.afterLeave = () => {
             if (pendingId === suspense.pendingId) {
-              move(pendingBranch!, container, anchor, MoveType.ENTER)
+              move(
+                pendingBranch!,
+                container,
+                next(activeBranch!),
+                MoveType.ENTER
+              )
               queuePostFlushCb(effects)
             }
           }
@@ -577,7 +582,6 @@ function createSuspenseBoundary(
       // invoke @fallback event
       triggerEvent(vnode, 'onFallback')
 
-      const anchor = next(activeBranch!)
       const mountFallback = () => {
         if (!suspense.isInFallback) {
           return
@@ -587,7 +591,7 @@ function createSuspenseBoundary(
           null,
           fallbackVNode,
           container,
-          anchor,
+          next(activeBranch!),
           parentComponent,
           null, // fallback tree will not have suspense context
           isSVG,
index 38fdf53cf4f69ae6a74f8bf6d75023fce2da62d7..58797d82e732629a4be0d9a465dfbaba948022cd 100644 (file)
@@ -1586,6 +1586,72 @@ describe('e2e: Transition', () => {
       expect(barMountSpy).toBeCalledTimes(1)
       expect(barMountSpy).toHaveBeenNthCalledWith(1, true, false, true)
     })
+
+    // #8105
+    test(
+      'trigger again when transition is not finished',
+      async () => {
+        await page().evaluate(duration => {
+          const { createApp, shallowRef, h } = (window as any).Vue
+          const One = {
+            async setup() {
+              return () => h('div', { class: 'test' }, 'one')
+            }
+          }
+          const Two = {
+            async setup() {
+              return () => h('div', { class: 'test' }, 'two')
+            }
+          }
+          createApp({
+            template: `
+            <div id="container">
+              <transition name="test" mode="out-in" duration="${duration}">
+                <Suspense>
+                  <component :is="view"/>
+                </Suspense>
+              </transition>
+            </div>
+            <button id="toggleBtn" @click="click">button</button>
+          `,
+            setup: () => {
+              const view = shallowRef(One)
+              const click = () => {
+                view.value = view.value === One ? Two : One
+              }
+              return { view, click }
+            }
+          }).mount('#app')
+        }, duration)
+
+        await nextFrame()
+        expect(await html('#container')).toBe(
+          '<div class="test test-enter-active test-enter-to">one</div>'
+        )
+
+        await transitionFinish()
+        expect(await html('#container')).toBe('<div class="test">one</div>')
+
+        // trigger twice
+        classWhenTransitionStart()
+        classWhenTransitionStart()
+        await nextFrame()
+        expect(await html('#container')).toBe(
+          '<div class="test test-leave-active test-leave-to">one</div>'
+        )
+
+        await transitionFinish()
+        await nextFrame()
+        expect(await html('#container')).toBe(
+          '<div class="test test-enter-active test-enter-to">one</div>'
+        )
+
+        await transitionFinish()
+        await nextFrame()
+        expect(await html('#container')).toBe('<div class="test">one</div>')
+      },
+      E2E_TIMEOUT
+    )
   })
 
   describe('transition with v-show', () => {