Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 109x 31x 31x 31x 78x 78x 1x 1x 78x 48x 78x 78x 109x 109x 109x 7x 78x 48x 78x 88x 86x 86x 78x 1x 77x | import type { Data } from '../component'
import type { RawSlots, Slots } from '../componentSlots'
import {
type ContextualRenderFn,
currentRenderingInstance,
} from '../componentRenderContext'
import {
Comment,
Fragment,
type VNode,
type VNodeArrayChildren,
createBlock,
createVNode,
isVNode,
openBlock,
} from '../vnode'
import { PatchFlags, SlotFlags, isSymbol } from '@vue/shared'
import { warn } from '../warning'
import { isAsyncWrapper } from '../apiAsyncComponent'
/**
* Compiler runtime helper for rendering `<slot/>`
* @private
*/
export function renderSlot(
slots: Slots,
name: string,
props: Data = {},
// this is not a user-facing function, so the fallback is always generated by
// the compiler and guaranteed to be a function returning an array
fallback?: () => VNodeArrayChildren,
noSlotted?: boolean,
): VNode {
if (
currentRenderingInstance!.ce ||
(currentRenderingInstance!.parent &&
isAsyncWrapper(currentRenderingInstance!.parent) &&
currentRenderingInstance!.parent.ce)
) {
const hasProps = Object.keys(props).length > 0
// in custom element mode, render <slot/> as actual slot outlets
// wrap it with a fragment because in shadowRoot: false mode the slot
// element gets replaced by injected content
if (name !== 'default') props.name = name
return (
openBlock(),
createBlock(
Fragment,
null,
[createVNode('slot', props, fallback && fallback())],
hasProps ? PatchFlags.BAIL : PatchFlags.STABLE_FRAGMENT,
)
)
}
let slot = slots[name]
if (__DEV__ && slot && slot.length > 1) {
warn(
`SSR-optimized slot function detected in a non-SSR-optimized render ` +
`function. You need to mark this component with $dynamic-slots in the ` +
`parent template.`,
)
slot = () => []
}
// a compiled slot disables block tracking by default to avoid manual
// invocation interfering with template-based block tracking, but in
// `renderSlot` we can be sure that it's template-based so we can force
// enable it.
if (slot && (slot as ContextualRenderFn)._c) {
;(slot as ContextualRenderFn)._d = false
}
openBlock()
const validSlotContent = slot && ensureValidVNode(slot(props))
const slotKey =
props.key ||
// slot content array of a dynamic conditional slot may have a branch
// key attached in the `createSlots` helper, respect that
(validSlotContent && (validSlotContent as any).key)
const rendered = createBlock(
Fragment,
{
key:
(slotKey && !isSymbol(slotKey) ? slotKey : `_${name}`) +
// #7256 force differentiate fallback content from actual content
(!validSlotContent && fallback ? '_fb' : ''),
},
validSlotContent || (fallback ? fallback() : []),
validSlotContent && (slots as RawSlots)._ === SlotFlags.STABLE
? PatchFlags.STABLE_FRAGMENT
: PatchFlags.BAIL,
)
if (!noSlotted && rendered.scopeId) {
rendered.slotScopeIds = [rendered.scopeId + '-s']
}
if (slot && (slot as ContextualRenderFn)._c) {
;(slot as ContextualRenderFn)._d = true
}
return rendered
}
export function ensureValidVNode(
vnodes: VNodeArrayChildren,
): VNodeArrayChildren | null {
return vnodes.some(child => {
Iif (!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
}
|