]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(Suspense): fallback should work with transition (#3968)
authoredison <daiwei521@126.com>
Mon, 21 Jun 2021 20:58:43 +0000 (04:58 +0800)
committerGitHub <noreply@github.com>
Mon, 21 Jun 2021 20:58:43 +0000 (16:58 -0400)
fix #3963

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

index d5d544469f3c118c1c46d3361df1fada02c03697..57ba92c6fcdcf0b30557201610f85a35d921b6d4 100644 (file)
@@ -551,6 +551,8 @@ function createSuspenseBoundary(
       if (delayEnter) {
         activeBranch!.transition!.afterLeave = mountFallback
       }
+      suspense.isInFallback = true
+
       // unmount current active branch
       unmount(
         activeBranch!,
@@ -559,7 +561,6 @@ function createSuspenseBoundary(
         true // shouldRemove
       )
 
-      suspense.isInFallback = true
       if (!delayEnter) {
         mountFallback()
       }
index eb56c4fd39b09a7cc1d844186fc6e391a7261c81..1465f9c9ecebca30ff7150b3341118438e3daea0 100644 (file)
@@ -1325,6 +1325,69 @@ describe('e2e: Transition', () => {
       },
       E2E_TIMEOUT
     )
+
+    // #3963
+    test(
+      'Suspense fallback should work with transition',
+      async () => {
+        await page().evaluate(() => {
+          const { createApp, shallowRef, h } = (window as any).Vue
+
+          const One = {
+            template: `<div>{{ msg }}</div>`,
+            setup() {
+              return new Promise(_resolve => {
+                // @ts-ignore
+                window.resolve = () =>
+                  _resolve({
+                    msg: 'success'
+                  })
+              })
+            }
+          }
+
+          createApp({
+            template: `
+              <div id="container">
+                <transition mode="out-in">
+                  <Suspense :timeout="0">
+                    <template #default>
+                      <component :is="view" />
+                    </template>
+                    <template #fallback>
+                      <div>Loading...</div>
+                    </template>
+                  </Suspense>
+                </transition>
+              </div>
+              <button id="toggleBtn" @click="click">button</button>
+            `,
+            setup: () => {
+              const view = shallowRef(null)
+              const click = () => {
+                view.value = view.value ? null : h(One)
+              }
+              return { view, click }
+            }
+          }).mount('#app')
+        })
+
+        expect(await html('#container')).toBe('<!---->')
+
+        await click('#toggleBtn')
+        await nextFrame()
+        expect(await html('#container')).toBe('<div class="">Loading...</div>')
+
+        await page().evaluate(() => {
+          // @ts-ignore
+          window.resolve()
+        })
+
+        await transitionFinish(duration * 2)
+        expect(await html('#container')).toBe('<div class="">success</div>')
+      },
+      E2E_TIMEOUT
+    )
   })
 
   describe('transition with v-show', () => {