// mark this as a compiled slot function.
// this is used in vnode.ts -> normalizeChildren() to set the slot
// rendering flag.
- renderFnWithContext._c = true
+ // also used to cache the normalized results to avoid repeated normalization
+ renderFnWithContext._c = renderFnWithContext
if (__COMPAT__ && isNonScopedSlot) {
renderFnWithContext._nonScoped = true
}
import { withCtx } from './componentRenderContext'
import { isHmrUpdating } from './hmr'
import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig'
+import { toRaw } from '@vue/reactivity'
export type Slot = (...args: any[]) => VNode[]
rawSlot: Function,
ctx: ComponentInternalInstance | null | undefined
): Slot =>
- withCtx((props: any) => {
+ (rawSlot as any)._c ||
+ (withCtx((props: any) => {
if (__DEV__ && currentInstance) {
warn(
`Slot "${key}" invoked outside of the render function: ` +
)
}
return normalizeSlotValue(rawSlot(props))
- }, ctx) as Slot
+ }, ctx) as Slot)
const normalizeObjectSlots = (
rawSlots: RawSlots,
if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
const type = (children as RawSlots)._
if (type) {
- instance.slots = children as InternalSlots
+ // users can get the shallow readonly version of the slots object through `this.$slots`,
+ // we should avoid the proxy object polluting the slots of the internal instance
+ instance.slots = toRaw(children as InternalSlots)
// make compiler marker non-enumerable
def(children as InternalSlots, '_', type)
} else {