Ver Fonte

fix(runtime-core): non-stable Fragment should always unmount its children (#2445)

fix #2444
HcySunYang há 5 anos atrás
pai
commit
fff62e2ee8

+ 42 - 0
packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts

@@ -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)
+  })
 })

+ 6 - 1
packages/runtime-core/src/renderer.ts

@@ -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)
       }