Просмотр исходного кода

fix(runtime-vapor): avoid duplicate parent boundary dirtying in vdom slots

daiwei 5 дней назад
Родитель
Сommit
c1df71d437

+ 31 - 0
packages/runtime-vapor/__tests__/componentSlots.spec.ts

@@ -579,6 +579,37 @@ describe('component: slots', () => {
       expect(boundary.markDirty).toHaveBeenCalledTimes(1)
     })
 
+    test('vdom slot dirties parent boundary once when switching from valid content to local fallback', async () => {
+      const show = ref(true)
+      const boundary = {
+        parent: null,
+        getLocalFallback: () => undefined,
+        markDirty: vi.fn(),
+      }
+      const instance = renderWithSlots({})
+      const app = createApp({ render: () => null })
+      app.use(vaporInteropPlugin)
+      const vapor = (app._context as any).vapor
+      const slotsRef = shallowRef({
+        default: () => (show.value ? [h('div', 'content')] : []),
+      })
+      const frag = withOwnedSlotBoundary(boundary, () =>
+        vapor.vdomSlot(slotsRef, 'default', {}, instance, () =>
+          template('fallback')(),
+        ),
+      )
+      const host = document.createElement('div')
+
+      insert(frag, host)
+      boundary.markDirty.mockClear()
+
+      show.value = false
+      await nextTick()
+
+      expect(host.innerHTML).toBe('fallback')
+      expect(boundary.markDirty).toHaveBeenCalledTimes(1)
+    })
+
     test('vdom slot still renders vapor fallback when slot content resolves empty', () => {
       const Child = defineVaporComponent({
         setup() {

+ 2 - 5
packages/runtime-vapor/src/vdomInterop.ts

@@ -1152,11 +1152,8 @@ function renderVDOMSlot(
     isContentValid: () => contentState.valid,
     runWithRenderCtx: fn => runWithFragmentRenderCtx(frag, fn),
     isDisposed: () => disposed,
-    onValidityChange: () => {
-      if (frag.inheritedSlotBoundary) {
-        frag.inheritedSlotBoundary.markDirty()
-      }
-    },
+    // `frag.onUpdated` already notifies the parent boundary.
+    onValidityChange: () => {},
   })
   const wrappedLocalFallback: BlockFn | undefined = fallback
     ? controller.wrapFallback(() => fallback(internals, parentComponent))