]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(suspense): fix suspense nested child updates in template mode
authorEvan You <yyx990803@gmail.com>
Tue, 20 Oct 2020 16:28:02 +0000 (12:28 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 20 Oct 2020 16:28:02 +0000 (12:28 -0400)
fix #2214

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

index 5602b4a7f14ae4e2f2e5d7a2b449ca73805b6290..e980047553298c04ac665c7d9b31b9f1d24f0026 100644 (file)
@@ -14,6 +14,7 @@ import {
   onErrorCaptured,
   shallowRef
 } from '@vue/runtime-test'
+import { createApp } from 'vue'
 
 describe('Suspense', () => {
   const deps: Promise<any>[] = []
@@ -1068,4 +1069,28 @@ describe('Suspense', () => {
     expect(serializeInner(root)).toBe(`<div>two</div>`)
     expect(calls).toEqual([`one mounted`, `one unmounted`, `two mounted`])
   })
+
+  // #2214
+  // Since suspense renders its own root like a component, it should not patch
+  // its content in optimized mode.
+  test('should not miss nested element updates when used in templates', async () => {
+    const n = ref(1)
+    const Comp = {
+      setup() {
+        return { n }
+      },
+      template: `
+      <Suspense>
+        <div><span>{{ n }}</span></div>
+      </Suspense>
+      `
+    }
+    const root = document.createElement('div')
+    createApp(Comp).mount(root)
+    expect(root.innerHTML).toBe(`<div><span>1</span></div>`)
+
+    n.value++
+    await nextTick()
+    expect(root.innerHTML).toBe(`<div><span>2</span></div>`)
+  })
 })
index 288139609a90bf3f8163bcfed792ded0c7648641..105af7315317f6b374b96f3369883ea1b937b433 100644 (file)
@@ -69,7 +69,6 @@ export const SuspenseImpl = {
         anchor,
         parentComponent,
         isSVG,
-        optimized,
         rendererInternals
       )
     }
@@ -121,8 +120,7 @@ function mountSuspense(
     null,
     parentComponent,
     suspense,
-    isSVG,
-    optimized
+    isSVG
   )
   // now check if we have encountered any async deps
   if (suspense.deps > 0) {
@@ -135,8 +133,7 @@ function mountSuspense(
       anchor,
       parentComponent,
       null, // fallback tree will not have suspense context
-      isSVG,
-      optimized
+      isSVG
     )
     setActiveBranch(suspense, vnode.ssFallback!)
   } else {
@@ -152,7 +149,6 @@ function patchSuspense(
   anchor: RendererNode | null,
   parentComponent: ComponentInternalInstance | null,
   isSVG: boolean,
-  optimized: boolean,
   { p: patch, um: unmount, o: { createElement } }: RendererInternals
 ) {
   const suspense = (n2.suspense = n1.suspense)!
@@ -173,8 +169,7 @@ function patchSuspense(
         null,
         parentComponent,
         suspense,
-        isSVG,
-        optimized
+        isSVG
       )
       if (suspense.deps <= 0) {
         suspense.resolve()
@@ -186,8 +181,7 @@ function patchSuspense(
           anchor,
           parentComponent,
           null, // fallback tree will not have suspense context
-          isSVG,
-          optimized
+          isSVG
         )
         setActiveBranch(suspense, newFallback)
       }
@@ -220,8 +214,7 @@ function patchSuspense(
           null,
           parentComponent,
           suspense,
-          isSVG,
-          optimized
+          isSVG
         )
         if (suspense.deps <= 0) {
           suspense.resolve()
@@ -233,8 +226,7 @@ function patchSuspense(
             anchor,
             parentComponent,
             null, // fallback tree will not have suspense context
-            isSVG,
-            optimized
+            isSVG
           )
           setActiveBranch(suspense, newFallback)
         }
@@ -247,8 +239,7 @@ function patchSuspense(
           anchor,
           parentComponent,
           suspense,
-          isSVG,
-          optimized
+          isSVG
         )
         // force resolve
         suspense.resolve(true)
@@ -261,8 +252,7 @@ function patchSuspense(
           null,
           parentComponent,
           suspense,
-          isSVG,
-          optimized
+          isSVG
         )
         if (suspense.deps <= 0) {
           suspense.resolve()
@@ -279,8 +269,7 @@ function patchSuspense(
         anchor,
         parentComponent,
         suspense,
-        isSVG,
-        optimized
+        isSVG
       )
       setActiveBranch(suspense, newBranch)
     } else {
@@ -300,8 +289,7 @@ function patchSuspense(
         null,
         parentComponent,
         suspense,
-        isSVG,
-        optimized
+        isSVG
       )
       if (suspense.deps <= 0) {
         // incoming branch has no async deps, resolve now.
@@ -327,7 +315,6 @@ export interface SuspenseBoundary {
   parent: SuspenseBoundary | null
   parentComponent: ComponentInternalInstance | null
   isSVG: boolean
-  optimized: boolean
   container: RendererElement
   hiddenContainer: RendererElement
   anchor: RendererNode | null
@@ -392,7 +379,6 @@ function createSuspenseBoundary(
     parent,
     parentComponent,
     isSVG,
-    optimized,
     container,
     hiddenContainer,
     anchor,
@@ -499,8 +485,7 @@ function createSuspenseBoundary(
         activeBranch,
         parentComponent,
         container,
-        isSVG,
-        optimized
+        isSVG
       } = suspense
 
       // invoke @fallback event
@@ -522,8 +507,7 @@ function createSuspenseBoundary(
           anchor,
           parentComponent,
           null, // fallback tree will not have suspense context
-          isSVG,
-          optimized
+          isSVG
         )
         setActiveBranch(suspense, fallbackVNode)
       }