fix(slots): should render fallback content when slot content contains no valid nodes (#2485)
fix #2347, fix #2461
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Data } from '../component'
|
||||
import { Slots, RawSlots } from '../componentSlots'
|
||||
import { Comment, isVNode } from '../vnode'
|
||||
import {
|
||||
VNodeArrayChildren,
|
||||
openBlock,
|
||||
@@ -42,15 +43,31 @@ export function renderSlot(
|
||||
// `renderSlot` we can be sure that it's template-based so we can force
|
||||
// enable it.
|
||||
isRenderingCompiledSlot++
|
||||
const rendered = (openBlock(),
|
||||
createBlock(
|
||||
openBlock()
|
||||
const validSlotContent = slot && ensureValidVNode(slot(props))
|
||||
const rendered = createBlock(
|
||||
Fragment,
|
||||
{ key: props.key },
|
||||
slot ? slot(props) : fallback ? fallback() : [],
|
||||
(slots as RawSlots)._ === SlotFlags.STABLE
|
||||
validSlotContent || (fallback ? fallback() : []),
|
||||
validSlotContent && (slots as RawSlots)._ === SlotFlags.STABLE
|
||||
? PatchFlags.STABLE_FRAGMENT
|
||||
: PatchFlags.BAIL
|
||||
))
|
||||
)
|
||||
isRenderingCompiledSlot--
|
||||
return rendered
|
||||
}
|
||||
|
||||
function ensureValidVNode(vnodes: VNodeArrayChildren) {
|
||||
return vnodes.some(child => {
|
||||
if (!isVNode(child)) return true
|
||||
if (child.type === Comment) return false
|
||||
if (
|
||||
child.type === Fragment &&
|
||||
!ensureValidVNode(child.children as VNodeArrayChildren)
|
||||
)
|
||||
return false
|
||||
return true
|
||||
})
|
||||
? vnodes
|
||||
: null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user