From 84f329af1ac866ed214630f71d3f4cc9eae152af Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Fri, 30 Apr 2021 12:36:44 +0800 Subject: [PATCH 1/2] fix(runtime-core): avoid the proxy object polluting the slots of the internal instance --- packages/runtime-core/src/componentRenderContext.ts | 3 ++- packages/runtime-core/src/componentSlots.ts | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/src/componentRenderContext.ts b/packages/runtime-core/src/componentRenderContext.ts index 78557484586..8dd3e9cabdc 100644 --- a/packages/runtime-core/src/componentRenderContext.ts +++ b/packages/runtime-core/src/componentRenderContext.ts @@ -83,7 +83,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 9fdb0d142db..28e6d875348 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 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 { From 216f5570f8279afae3fe54d3e53d0112da35abfc Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Fri, 30 Apr 2021 14:24:29 +0800 Subject: [PATCH 2/2] chore: comments --- packages/runtime-core/src/componentSlots.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/componentSlots.ts b/packages/runtime-core/src/componentSlots.ts index 28e6d875348..7e0fe3cb61b 100644 --- a/packages/runtime-core/src/componentSlots.ts +++ b/packages/runtime-core/src/componentSlots.ts @@ -130,7 +130,7 @@ export const initSlots = ( if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) { const type = (children as RawSlots)._ if (type) { - // users can get the shallow readonly object through this.$slots, + // 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