Skip to content

Commit b498eec

Browse files
committed
fix(runtime-vapor): render slot fallback if slot content is not a valid block
close #13668
1 parent 56a7f9d commit b498eec

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

packages/runtime-vapor/__tests__/componentSlots.spec.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,5 +502,64 @@ describe('component: slots', () => {
502502
await nextTick()
503503
expect(host.innerHTML).toBe('<div><h1></h1><!--slot--></div>')
504504
})
505+
506+
test('render fallback when slot content is not valid', async () => {
507+
const Child = {
508+
setup() {
509+
return createSlot('default', null, () =>
510+
document.createTextNode('fallback'),
511+
)
512+
},
513+
}
514+
515+
const { html } = define({
516+
setup() {
517+
return createComponent(Child, null, {
518+
default: () => {
519+
return template('<!--comment-->')()
520+
},
521+
})
522+
},
523+
}).render()
524+
525+
expect(html()).toBe('fallback<!--slot-->')
526+
})
527+
528+
test('render fallback when v-if condition is false', async () => {
529+
const Child = {
530+
setup() {
531+
return createSlot('default', null, () =>
532+
document.createTextNode('fallback'),
533+
)
534+
},
535+
}
536+
537+
const toggle = ref(false)
538+
539+
const { html } = define({
540+
setup() {
541+
return createComponent(Child, null, {
542+
default: () => {
543+
return createIf(
544+
() => toggle.value,
545+
() => {
546+
return document.createTextNode('content')
547+
},
548+
)
549+
},
550+
})
551+
},
552+
}).render()
553+
554+
expect(html()).toBe('fallback<!--if--><!--slot-->')
555+
556+
toggle.value = true
557+
await nextTick()
558+
expect(html()).toBe('content<!--if--><!--slot-->')
559+
560+
toggle.value = false
561+
await nextTick()
562+
expect(html()).toBe('fallback<!--if--><!--slot-->')
563+
})
505564
})
506565
})

packages/runtime-vapor/src/block.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,14 @@ export class DynamicFragment extends VaporFragment {
6767

6868
if (this.fallback && !isValidBlock(this.nodes)) {
6969
parent && remove(this.nodes, parent)
70-
this.nodes =
71-
(this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
72-
[]
70+
// render fallback for dynamic fragment
71+
if (this.nodes instanceof DynamicFragment) {
72+
this.nodes.update(this.fallback)
73+
} else {
74+
this.nodes =
75+
(this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
76+
[]
77+
}
7378
parent && insert(this.nodes, parent, this.anchor)
7479
}
7580

packages/runtime-vapor/src/componentSlots.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export function createSlot(
126126
const renderSlot = () => {
127127
const slot = getSlot(rawSlots, isFunction(name) ? name() : name)
128128
if (slot) {
129+
fragment.fallback = fallback
129130
// create and cache bound version of the slot to make it stable
130131
// so that we avoid unnecessary updates if it resolves to the same slot
131132
fragment.update(

0 commit comments

Comments
 (0)