Skip to content

Commit 3896780

Browse files
committed
fix(vdomInterop): handle forwarded vapor slots during render VDOM slot
1 parent 187396d commit 3896780

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

packages/runtime-vapor/src/componentProps.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ export function hasAttrFromRawProps(rawProps: RawProps, key: string): boolean {
214214
if (dynamicSources) {
215215
let i = dynamicSources.length
216216
while (i--) {
217-
if (hasOwn(resolveSource(dynamicSources[i]), key)) {
217+
const source = resolveSource(dynamicSources[i])
218+
if (source && hasOwn(source, key)) {
218219
return true
219220
}
220221
}

packages/runtime-vapor/src/vdomInterop.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@ import {
2929
mountComponent,
3030
unmountComponent,
3131
} 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'
3340
import { EMPTY_OBJ, extend, isFunction } from '@vue/shared'
3441
import { type RawProps, rawPropsProxyHandlers } from './componentProps'
3542
import type { RawSlots, VaporSlot } from './componentSlots'
@@ -279,7 +286,36 @@ function renderVDOMSlot(
279286
false,
280287
)
281288
} 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) {
283319
if (fallbackNodes) {
284320
remove(fallbackNodes, parentNode)
285321
fallbackNodes = undefined

0 commit comments

Comments
 (0)