@@ -29,7 +29,14 @@ import {
29
29
mountComponent ,
30
30
unmountComponent ,
31
31
} from './component'
32
- import { type Block , VaporFragment , insert , remove } from './block'
32
+ import {
33
+ type Block ,
34
+ VaporFragment ,
35
+ insert ,
36
+ isFragment ,
37
+ isValidBlock ,
38
+ remove ,
39
+ } from './block'
33
40
import { EMPTY_OBJ , extend , isFunction } from '@vue/shared'
34
41
import { type RawProps , rawPropsProxyHandlers } from './componentProps'
35
42
import type { RawSlots , VaporSlot } from './componentSlots'
@@ -279,7 +286,36 @@ function renderVDOMSlot(
279
286
false ,
280
287
)
281
288
} else {
282
- if ( ( vnode . children as any [ ] ) . length ) {
289
+ let isValidSlotContent
290
+ let children = vnode . children as any [ ]
291
+ /*
292
+ * Handle forwarded vapor slot inside VDOM slot
293
+ * Example: In a vapor component template:
294
+ * <VDOMComp>
295
+ * <template #header>
296
+ * <slot name="header" /> <!-- This vapor slot gets forwarded -->
297
+ * </template>
298
+ * </VDOMComp>
299
+ */
300
+ let vaporSlot
301
+ if ( children . length === 1 && ( vaporSlot = children [ 0 ] . vs ) ) {
302
+ const block = vaporSlot . slot ( props )
303
+ isValidSlotContent =
304
+ isValidBlock ( block ) ||
305
+ /*
306
+ * If block is a vapor fragment with insert, it indicates a forwarded VDOM slot
307
+ * Example: In a VDOM component template:
308
+ * <VaporComp>
309
+ * <template #header>
310
+ * <slot name="header" /> <!-- This VDOM slot gets forwarded -->
311
+ * </template>
312
+ * </VaporComp>
313
+ */
314
+ ( isFragment ( block ) && block . insert )
315
+ } else {
316
+ isValidSlotContent = children . length > 0
317
+ }
318
+ if ( isValidSlotContent ) {
283
319
if ( fallbackNodes ) {
284
320
remove ( fallbackNodes , parentNode )
285
321
fallbackNodes = undefined
0 commit comments