fix(runtime-core): avoid the proxy object polluting the slots of the internal instance (#3698)
fix #3695
This commit is contained in:
parent
7c74feb3dc
commit
4ce0df6ef1
@ -89,7 +89,8 @@ export function withCtx(
|
|||||||
// mark this as a compiled slot function.
|
// mark this as a compiled slot function.
|
||||||
// this is used in vnode.ts -> normalizeChildren() to set the slot
|
// this is used in vnode.ts -> normalizeChildren() to set the slot
|
||||||
// rendering flag.
|
// rendering flag.
|
||||||
renderFnWithContext._c = true
|
// also used to cache the normalized results to avoid repeated normalization
|
||||||
|
renderFnWithContext._c = renderFnWithContext
|
||||||
if (__COMPAT__ && isNonScopedSlot) {
|
if (__COMPAT__ && isNonScopedSlot) {
|
||||||
renderFnWithContext._nonScoped = true
|
renderFnWithContext._nonScoped = true
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import { isKeepAlive } from './components/KeepAlive'
|
|||||||
import { withCtx } from './componentRenderContext'
|
import { withCtx } from './componentRenderContext'
|
||||||
import { isHmrUpdating } from './hmr'
|
import { isHmrUpdating } from './hmr'
|
||||||
import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig'
|
import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig'
|
||||||
|
import { toRaw } from '@vue/reactivity'
|
||||||
|
|
||||||
export type Slot = (...args: any[]) => VNode[]
|
export type Slot = (...args: any[]) => VNode[]
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ const normalizeSlot = (
|
|||||||
rawSlot: Function,
|
rawSlot: Function,
|
||||||
ctx: ComponentInternalInstance | null | undefined
|
ctx: ComponentInternalInstance | null | undefined
|
||||||
): Slot =>
|
): Slot =>
|
||||||
withCtx((props: any) => {
|
(rawSlot as any)._c ||
|
||||||
|
(withCtx((props: any) => {
|
||||||
if (__DEV__ && currentInstance) {
|
if (__DEV__ && currentInstance) {
|
||||||
warn(
|
warn(
|
||||||
`Slot "${key}" invoked outside of the render function: ` +
|
`Slot "${key}" invoked outside of the render function: ` +
|
||||||
@ -71,7 +73,7 @@ const normalizeSlot = (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
return normalizeSlotValue(rawSlot(props))
|
return normalizeSlotValue(rawSlot(props))
|
||||||
}, ctx) as Slot
|
}, ctx) as Slot)
|
||||||
|
|
||||||
const normalizeObjectSlots = (
|
const normalizeObjectSlots = (
|
||||||
rawSlots: RawSlots,
|
rawSlots: RawSlots,
|
||||||
@ -128,7 +130,9 @@ export const initSlots = (
|
|||||||
if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
|
if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
|
||||||
const type = (children as RawSlots)._
|
const type = (children as RawSlots)._
|
||||||
if (type) {
|
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
|
// make compiler marker non-enumerable
|
||||||
def(children as InternalSlots, '_', type)
|
def(children as InternalSlots, '_', type)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user