mirror of https://github.com/vuejs/core.git
fix(runtime-vapor): render slot fallback if slot content is not a valid block
close #13668
This commit is contained in:
parent
56a7f9dd18
commit
b498eecba5
|
@ -502,5 +502,64 @@ describe('component: slots', () => {
|
|||
await nextTick()
|
||||
expect(host.innerHTML).toBe('<div><h1></h1><!--slot--></div>')
|
||||
})
|
||||
|
||||
test('render fallback when slot content is not valid', async () => {
|
||||
const Child = {
|
||||
setup() {
|
||||
return createSlot('default', null, () =>
|
||||
document.createTextNode('fallback'),
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
const { html } = define({
|
||||
setup() {
|
||||
return createComponent(Child, null, {
|
||||
default: () => {
|
||||
return template('<!--comment-->')()
|
||||
},
|
||||
})
|
||||
},
|
||||
}).render()
|
||||
|
||||
expect(html()).toBe('fallback<!--slot-->')
|
||||
})
|
||||
|
||||
test('render fallback when v-if condition is false', 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-->')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -67,9 +67,14 @@ export class DynamicFragment extends VaporFragment {
|
|||
|
||||
if (this.fallback && !isValidBlock(this.nodes)) {
|
||||
parent && remove(this.nodes, parent)
|
||||
this.nodes =
|
||||
(this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
|
||||
[]
|
||||
// render fallback for dynamic fragment
|
||||
if (this.nodes instanceof DynamicFragment) {
|
||||
this.nodes.update(this.fallback)
|
||||
} else {
|
||||
this.nodes =
|
||||
(this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
|
||||
[]
|
||||
}
|
||||
parent && insert(this.nodes, parent, this.anchor)
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ export function createSlot(
|
|||
const renderSlot = () => {
|
||||
const slot = getSlot(rawSlots, isFunction(name) ? name() : name)
|
||||
if (slot) {
|
||||
fragment.fallback = fallback
|
||||
// create and cache bound version of the slot to make it stable
|
||||
// so that we avoid unnecessary updates if it resolves to the same slot
|
||||
fragment.update(
|
||||
|
|
Loading…
Reference in New Issue