fix(runtime-vapor): use slot fallback on initial render

This commit is contained in:
daiwei 2025-04-02 16:30:55 +08:00
parent 9ab8e4c0c9
commit 53564e01b7
2 changed files with 51 additions and 2 deletions

View 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)

View 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
}),