fix(runtime-core): avoid the proxy object polluting the slots of the internal instance (#3698)

fix #3695
This commit is contained in:
HcySunYang 2021-05-25 06:17:37 +08:00 committed by GitHub
parent 7c74feb3dc
commit 4ce0df6ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 4 deletions

View File

@ -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
} }

View File

@ -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 {