@@ -11,7 +11,6 @@ import {
|
||||
isFunction,
|
||||
EMPTY_OBJ,
|
||||
ShapeFlags,
|
||||
PatchFlags,
|
||||
extend,
|
||||
def
|
||||
} from '@vue/shared'
|
||||
@@ -28,6 +27,11 @@ export type InternalSlots = {
|
||||
|
||||
export type Slots = Readonly<InternalSlots>
|
||||
|
||||
export const enum CompiledSlotTypes {
|
||||
STATIC = 1,
|
||||
DYNAMIC = 2
|
||||
}
|
||||
|
||||
export type RawSlots = {
|
||||
[name: string]: unknown
|
||||
// manual render fn hint to skip forced children updates
|
||||
@@ -40,7 +44,7 @@ export type RawSlots = {
|
||||
// object may be directly passed down to a child component in a manual
|
||||
// render function, and the optimization hint need to be on the slot object
|
||||
// itself to be preserved.
|
||||
_?: 1
|
||||
_?: CompiledSlotTypes
|
||||
}
|
||||
|
||||
const isInternalKey = (key: string) => key[0] === '_' || key === '$stable'
|
||||
@@ -105,10 +109,11 @@ export const initSlots = (
|
||||
children: VNodeNormalizedChildren
|
||||
) => {
|
||||
if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
|
||||
if ((children as RawSlots)._ === 1) {
|
||||
const type = (children as RawSlots)._
|
||||
if (type) {
|
||||
instance.slots = children as InternalSlots
|
||||
// make compiler marker non-enumerable
|
||||
def(children as InternalSlots, '_', 1)
|
||||
def(children as InternalSlots, '_', type)
|
||||
} else {
|
||||
normalizeObjectSlots(children as RawSlots, (instance.slots = {}))
|
||||
}
|
||||
@@ -129,21 +134,20 @@ export const updateSlots = (
|
||||
let needDeletionCheck = true
|
||||
let deletionComparisonTarget = EMPTY_OBJ
|
||||
if (vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
|
||||
if ((children as RawSlots)._ === 1) {
|
||||
const type = (children as RawSlots)._
|
||||
if (type) {
|
||||
// compiled slots.
|
||||
if (__DEV__ && isHmrUpdating) {
|
||||
// Parent was HMR updated so slot content may have changed.
|
||||
// force update slots and mark instance for hmr as well
|
||||
extend(slots, children as Slots)
|
||||
} else if (
|
||||
// bail on dynamic slots (v-if, v-for, reference of scope variables)
|
||||
!(vnode.patchFlag & PatchFlags.DYNAMIC_SLOTS)
|
||||
) {
|
||||
} else if (type === CompiledSlotTypes.STATIC) {
|
||||
// compiled AND static.
|
||||
// no need to update, and skip stale slots removal.
|
||||
needDeletionCheck = false
|
||||
} else {
|
||||
// compiled but dynamic - update slots, but skip normalization.
|
||||
// compiled but dynamic (v-if/v-for on slots) - update slots, but skip
|
||||
// normalization.
|
||||
extend(slots, children as Slots)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Data } from '../component'
|
||||
import { Slots } from '../componentSlots'
|
||||
import { Slots, RawSlots, CompiledSlotTypes } from '../componentSlots'
|
||||
import {
|
||||
VNodeArrayChildren,
|
||||
openBlock,
|
||||
@@ -39,7 +39,9 @@ export function renderSlot(
|
||||
Fragment,
|
||||
{ key: props.key },
|
||||
slot ? slot(props) : fallback ? fallback() : [],
|
||||
slots._ ? PatchFlags.STABLE_FRAGMENT : PatchFlags.BAIL
|
||||
(slots as RawSlots)._ === CompiledSlotTypes.STATIC
|
||||
? PatchFlags.STABLE_FRAGMENT
|
||||
: PatchFlags.BAIL
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user