Skip to content

Commit 6df53d8

Browse files
committedApr 16, 2024··
fix(runtime-core): use same internal object mechanism for slots
close #10709
1 parent 6930e60 commit 6df53d8

File tree

4 files changed

+20
-15
lines changed

4 files changed

+20
-15
lines changed
 

‎packages/runtime-core/src/componentProps.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { createPropsDefaultThis } from './compat/props'
3838
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
3939
import { DeprecationTypes } from './compat/compatConfig'
4040
import { shouldSkipAttr } from './compat/attrsFallthrough'
41+
import { createInternalObject } from './internalObject'
4142

4243
export type ComponentPropsOptions<P = Data> =
4344
| ComponentObjectPropsOptions<P>
@@ -185,21 +186,14 @@ type NormalizedProp =
185186
export type NormalizedProps = Record<string, NormalizedProp>
186187
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
187188

188-
/**
189-
* Used during vnode props normalization to check if the vnode props is the
190-
* attrs object of a component via `Object.getPrototypeOf`. This is more
191-
* performant than defining a non-enumerable property.
192-
*/
193-
export const attrsProto = {}
194-
195189
export function initProps(
196190
instance: ComponentInternalInstance,
197191
rawProps: Data | null,
198192
isStateful: number, // result of bitwise flag comparison
199193
isSSR = false,
200194
) {
201195
const props: Data = {}
202-
const attrs: Data = Object.create(attrsProto)
196+
const attrs: Data = createInternalObject()
203197

204198
instance.propsDefaults = Object.create(null)
205199

‎packages/runtime-core/src/componentSlots.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig'
2424
import { toRaw } from '@vue/reactivity'
2525
import { trigger } from '@vue/reactivity'
2626
import { TriggerOpTypes } from '@vue/reactivity'
27+
import { createInternalObject } from './internalObject'
2728

2829
export type Slot<T extends any = any> = (
2930
...args: IfAny<T, any[], [T] | (T extends undefined ? [] : never)>
@@ -177,12 +178,12 @@ export const initSlots = (
177178
} else {
178179
normalizeObjectSlots(
179180
children as RawSlots,
180-
(instance.slots = {}),
181+
(instance.slots = createInternalObject()),
181182
instance,
182183
)
183184
}
184185
} else {
185-
instance.slots = {}
186+
instance.slots = createInternalObject()
186187
if (children) {
187188
normalizeVNodeSlots(instance, children)
188189
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Used during vnode props/slots normalization to check if the vnode props/slots
3+
* are the internal attrs / slots object of a component via
4+
* `Object.getPrototypeOf`. This is more performant than defining a
5+
* non-enumerable property. (one of the optimizations done for ssr-benchmark)
6+
*/
7+
const internalObjectProto = Object.create(null)
Has conversations. Original line has conversations.
8+
9+
export const createInternalObject = () => Object.create(internalObjectProto)
10+
11+
export const isInternalObject = (obj: object) =>
12+
Object.getPrototypeOf(obj) === internalObjectProto

‎packages/runtime-core/src/vnode.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import { convertLegacyVModelProps } from './compat/componentVModel'
5555
import { defineLegacyVNodeProperties } from './compat/renderFn'
5656
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
5757
import type { ComponentPublicInstance } from './componentPublicInstance'
58-
import { attrsProto } from './componentProps'
58+
import { isInternalObject } from './internalObject'
5959

6060
export const Fragment = Symbol.for('v-fgt') as any as {
6161
__isFragment: true
@@ -617,9 +617,7 @@ function _createVNode(
617617

618618
export function guardReactiveProps(props: (Data & VNodeProps) | null) {
619619
if (!props) return null
620-
return isProxy(props) || Object.getPrototypeOf(props) === attrsProto
621-
? extend({}, props)
622-
: props
620+
return isProxy(props) || isInternalObject(props) ? extend({}, props) : props
623621
}
624622

625623
export function cloneVNode<T, U>(
@@ -791,7 +789,7 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
791789
} else {
792790
type = ShapeFlags.SLOTS_CHILDREN
793791
const slotFlag = (children as RawSlots)._
794-
if (!slotFlag) {
792+
if (!slotFlag && !isInternalObject(children)) {
795793
// if slots are not normalized, attach context instance
796794
// (compiled / normalized slots already have context)
797795
;(children as RawSlots)._ctx = currentRenderingInstance

0 commit comments

Comments
 (0)
Please sign in to comment.