Procházet zdrojové kódy

fix(runtime-vapor): avoid fast remove for component v-for

daiwei před 2 týdny
rodič
revize
8f6b772a9e

+ 29 - 0
packages/runtime-vapor/__tests__/for.spec.ts

@@ -20,6 +20,7 @@ import {
   type Ref,
   nextTick,
   onScopeDispose,
+  onUnmounted,
   reactive,
   readonly,
   ref,
@@ -1730,6 +1731,34 @@ describe('createFor', () => {
       )
     })
 
+    test('component blocks are unmounted when clearing with fast remove', async () => {
+      const items = ref([1, 2])
+      const unmounted = vi.fn()
+      const Child = defineVaporComponent({
+        setup() {
+          onUnmounted(unmounted)
+          return template('<span>child</span>')()
+        },
+      })
+
+      const { html } = define(() => {
+        return createFor(
+          () => items.value,
+          () => createComponent(Child),
+          undefined,
+          VaporVForFlags.FAST_REMOVE | VaporVForFlags.IS_COMPONENT,
+        )
+      }).render()
+
+      expect(html()).toBe('<span>child</span><span>child</span><!--for-->')
+
+      items.value = []
+      await nextTick()
+
+      expect(html()).toBe('<!--for-->')
+      expect(unmounted).toHaveBeenCalledTimes(2)
+    })
+
     test('slot fallback fragments can be reordered and removed', async () => {
       const items = ref([
         { id: 'a', text: 'A' },

+ 2 - 1
packages/runtime-vapor/src/apiCreateFor.ts

@@ -119,8 +119,9 @@ export const createFor = (
 
   const frag = new ForFragment(oldBlocks)
   const instance = currentInstance!
-  const canUseFastRemove = !!(flags & VaporVForFlags.FAST_REMOVE)
   const isComponent = !!(flags & VaporVForFlags.IS_COMPONENT)
+  const canUseFastRemove =
+    !!(flags & VaporVForFlags.FAST_REMOVE) && !isComponent
   const isSingleNode = !!(flags & VaporVForFlags.IS_SINGLE_NODE)
   const isFragment = !!(flags & VaporVForFlags.IS_FRAGMENT)