From: HcySunYang Date: Mon, 24 May 2021 22:17:37 +0000 (+0800) Subject: fix(runtime-core): avoid the proxy object polluting the slots of the internal instanc... X-Git-Tag: v3.1.0-beta.4~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ce0df6ef1a31ee45402e61e01777e3836b2c223;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-core): avoid the proxy object polluting the slots of the internal instance (#3698) fix #3695 --- diff --git a/packages/runtime-core/src/componentRenderContext.ts b/packages/runtime-core/src/componentRenderContext.ts index 18dcd6f2f8..a25756864e 100644 --- a/packages/runtime-core/src/componentRenderContext.ts +++ b/packages/runtime-core/src/componentRenderContext.ts @@ -89,7 +89,8 @@ export function withCtx( // 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 } diff --git a/packages/runtime-core/src/componentSlots.ts b/packages/runtime-core/src/componentSlots.ts index 9fdb0d142d..7e0fe3cb61 100644 --- a/packages/runtime-core/src/componentSlots.ts +++ b/packages/runtime-core/src/componentSlots.ts @@ -20,6 +20,7 @@ import { isKeepAlive } from './components/KeepAlive' 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[] @@ -62,7 +63,8 @@ const normalizeSlot = ( 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: ` + @@ -71,7 +73,7 @@ const normalizeSlot = ( ) } return normalizeSlotValue(rawSlot(props)) - }, ctx) as Slot + }, ctx) as Slot) const normalizeObjectSlots = ( rawSlots: RawSlots, @@ -128,7 +130,9 @@ export const initSlots = ( 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 {