]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-vapor): use slot fallback on initial render edison/fix/vaporRenderSlotfallback 13144/head
authordaiwei <daiwei521@126.com>
Wed, 2 Apr 2025 08:30:55 +0000 (16:30 +0800)
committerdaiwei <daiwei521@126.com>
Wed, 2 Apr 2025 08:47:50 +0000 (16:47 +0800)
packages/runtime-vapor/__tests__/componentSlots.spec.ts
packages/runtime-vapor/src/componentSlots.ts

index 58076fff9eea213c8180d87ef5ed089951560798..b577a18c58bbb22b993900863ab0ba204433f78e 100644 (file)
@@ -469,6 +469,43 @@ describe('component: slots', () => {
       expect(html()).toBe('content<!--if--><!--slot-->')
     })
 
+    test('use fallback on initial render', async () => {
+      const Child = {
+        setup() {
+          return createSlot('default', null, () =>
+            document.createTextNode('fallback'),
+          )
+        },
+      }
+
+      const toggle = ref(false)
+
+      const { html } = define({
+        setup() {
+          return createComponent(Child, null, {
+            default: () => {
+              return createIf(
+                () => toggle.value,
+                () => {
+                  return document.createTextNode('content')
+                },
+              )
+            },
+          })
+        },
+      }).render()
+
+      expect(html()).toBe('fallback<!--if--><!--slot-->')
+
+      toggle.value = true
+      await nextTick()
+      expect(html()).toBe('content<!--if--><!--slot-->')
+
+      toggle.value = false
+      await nextTick()
+      expect(html()).toBe('fallback<!--if--><!--slot-->')
+    })
+
     test('dynamic slot work with v-if', async () => {
       const val = ref('header')
       const toggle = ref(false)
index 74296e09466359d9fddc37305b032b4e99741010..8b9a078d90b4db0bdbbe6144aaacb6d2fe40a532 100644 (file)
@@ -1,5 +1,11 @@
 import { EMPTY_OBJ, NO, hasOwn, isArray, isFunction } from '@vue/shared'
-import { type Block, type BlockFn, DynamicFragment, insert } from './block'
+import {
+  type Block,
+  type BlockFn,
+  DynamicFragment,
+  insert,
+  isValidBlock,
+} from './block'
 import { rawPropsProxyHandlers } from './componentProps'
 import { currentInstance, isRef } from '@vue/runtime-dom'
 import type { LooseRawProps, VaporComponentInstance } from './component'
@@ -127,7 +133,13 @@ export function createSlot(
             (slot._bound = () => {
               const slotContent = slot(slotProps)
               if (slotContent instanceof DynamicFragment) {
-                slotContent.fallback = fallback
+                if (
+                  (slotContent.fallback = fallback) &&
+                  !isValidBlock(slotContent.nodes)
+                ) {
+                  // use fallback if the slot content is invalid
+                  slotContent.update(fallback)
+                }
               }
               return slotContent
             }),