]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): non-stable Fragment should always unmount its children (#2445)
authorHcySunYang <HcySunYang@outlook.com>
Tue, 20 Oct 2020 18:59:55 +0000 (02:59 +0800)
committerGitHub <noreply@github.com>
Tue, 20 Oct 2020 18:59:55 +0000 (14:59 -0400)
fix #2444

packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts
packages/runtime-core/src/renderer.ts

index 8b674b8a3957af0623835eec3cb933db1e512e87..24f496caa79eee65cb781aac3fc4fc6fba9370b3 100644 (file)
@@ -475,4 +475,46 @@ describe('renderer: optimized mode', () => {
     render(null, root)
     expect(spy).toHaveBeenCalledTimes(1)
   })
+
+  // #2444
+  // `KEYED_FRAGMENT` and `UNKEYED_FRAGMENT` always need to diff its children
+  test('non-stable Fragment always need to diff its children', () => {
+    const spyA = jest.fn()
+    const spyB = jest.fn()
+    const ChildA = {
+      setup() {
+        onBeforeUnmount(spyA)
+        return () => 'child'
+      }
+    }
+    const ChildB = {
+      setup() {
+        onBeforeUnmount(spyB)
+        return () => 'child'
+      }
+    }
+    const Parent = () => (
+      openBlock(),
+      createBlock('div', null, [
+        (openBlock(true),
+        createBlock(
+          Fragment,
+          null,
+          [createVNode(ChildA, { key: 0 })],
+          128 /* KEYED_FRAGMENT */
+        )),
+        (openBlock(true),
+        createBlock(
+          Fragment,
+          null,
+          [createVNode(ChildB)],
+          256 /* UNKEYED_FRAGMENT */
+        ))
+      ])
+    )
+    render(h(Parent), root)
+    render(null, root)
+    expect(spyA).toHaveBeenCalledTimes(1)
+    expect(spyB).toHaveBeenCalledTimes(1)
+  })
 })
index db47c15ad5ef73425904c1a0c93e55ac0c92e1cc..f0182c16f6405e8ab14dc3b4c603a4b101e6ee84 100644 (file)
@@ -2038,7 +2038,12 @@ function baseCreateRenderer(
           false,
           true
         )
-      } else if (!optimized && shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+      } else if (
+        (type === Fragment &&
+          (patchFlag & PatchFlags.KEYED_FRAGMENT ||
+            patchFlag & PatchFlags.UNKEYED_FRAGMENT)) ||
+        (!optimized && shapeFlag & ShapeFlags.ARRAY_CHILDREN)
+      ) {
         unmountChildren(children as VNode[], parentComponent, parentSuspense)
       }