diff --git a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts b/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts index 8b674b8a..24f496ca 100644 --- a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts +++ b/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) + }) }) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index db47c15a..f0182c16 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/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) }