mirror of https://github.com/vuejs/core.git
fix(runtime-core): use same internal object mechanism for slots
close #10709
This commit is contained in:
parent
6930e60787
commit
6df53d85a2
|
@ -38,6 +38,7 @@ import { createPropsDefaultThis } from './compat/props'
|
||||||
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
|
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
|
||||||
import { DeprecationTypes } from './compat/compatConfig'
|
import { DeprecationTypes } from './compat/compatConfig'
|
||||||
import { shouldSkipAttr } from './compat/attrsFallthrough'
|
import { shouldSkipAttr } from './compat/attrsFallthrough'
|
||||||
|
import { createInternalObject } from './internalObject'
|
||||||
|
|
||||||
export type ComponentPropsOptions<P = Data> =
|
export type ComponentPropsOptions<P = Data> =
|
||||||
| ComponentObjectPropsOptions<P>
|
| ComponentObjectPropsOptions<P>
|
||||||
|
@ -185,13 +186,6 @@ type NormalizedProp =
|
||||||
export type NormalizedProps = Record<string, NormalizedProp>
|
export type NormalizedProps = Record<string, NormalizedProp>
|
||||||
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
|
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
|
||||||
|
|
||||||
/**
|
|
||||||
* Used during vnode props normalization to check if the vnode props is the
|
|
||||||
* attrs object of a component via `Object.getPrototypeOf`. This is more
|
|
||||||
* performant than defining a non-enumerable property.
|
|
||||||
*/
|
|
||||||
export const attrsProto = {}
|
|
||||||
|
|
||||||
export function initProps(
|
export function initProps(
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
rawProps: Data | null,
|
rawProps: Data | null,
|
||||||
|
@ -199,7 +193,7 @@ export function initProps(
|
||||||
isSSR = false,
|
isSSR = false,
|
||||||
) {
|
) {
|
||||||
const props: Data = {}
|
const props: Data = {}
|
||||||
const attrs: Data = Object.create(attrsProto)
|
const attrs: Data = createInternalObject()
|
||||||
|
|
||||||
instance.propsDefaults = Object.create(null)
|
instance.propsDefaults = Object.create(null)
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig'
|
||||||
import { toRaw } from '@vue/reactivity'
|
import { toRaw } from '@vue/reactivity'
|
||||||
import { trigger } from '@vue/reactivity'
|
import { trigger } from '@vue/reactivity'
|
||||||
import { TriggerOpTypes } from '@vue/reactivity'
|
import { TriggerOpTypes } from '@vue/reactivity'
|
||||||
|
import { createInternalObject } from './internalObject'
|
||||||
|
|
||||||
export type Slot<T extends any = any> = (
|
export type Slot<T extends any = any> = (
|
||||||
...args: IfAny<T, any[], [T] | (T extends undefined ? [] : never)>
|
...args: IfAny<T, any[], [T] | (T extends undefined ? [] : never)>
|
||||||
|
@ -177,12 +178,12 @@ export const initSlots = (
|
||||||
} else {
|
} else {
|
||||||
normalizeObjectSlots(
|
normalizeObjectSlots(
|
||||||
children as RawSlots,
|
children as RawSlots,
|
||||||
(instance.slots = {}),
|
(instance.slots = createInternalObject()),
|
||||||
instance,
|
instance,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
instance.slots = {}
|
instance.slots = createInternalObject()
|
||||||
if (children) {
|
if (children) {
|
||||||
normalizeVNodeSlots(instance, children)
|
normalizeVNodeSlots(instance, children)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Used during vnode props/slots normalization to check if the vnode props/slots
|
||||||
|
* are the internal attrs / slots object of a component via
|
||||||
|
* `Object.getPrototypeOf`. This is more performant than defining a
|
||||||
|
* non-enumerable property. (one of the optimizations done for ssr-benchmark)
|
||||||
|
*/
|
||||||
|
const internalObjectProto = Object.create(null)
|
||||||
|
|
||||||
|
export const createInternalObject = () => Object.create(internalObjectProto)
|
||||||
|
|
||||||
|
export const isInternalObject = (obj: object) =>
|
||||||
|
Object.getPrototypeOf(obj) === internalObjectProto
|
|
@ -55,7 +55,7 @@ import { convertLegacyVModelProps } from './compat/componentVModel'
|
||||||
import { defineLegacyVNodeProperties } from './compat/renderFn'
|
import { defineLegacyVNodeProperties } from './compat/renderFn'
|
||||||
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
|
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
|
||||||
import type { ComponentPublicInstance } from './componentPublicInstance'
|
import type { ComponentPublicInstance } from './componentPublicInstance'
|
||||||
import { attrsProto } from './componentProps'
|
import { isInternalObject } from './internalObject'
|
||||||
|
|
||||||
export const Fragment = Symbol.for('v-fgt') as any as {
|
export const Fragment = Symbol.for('v-fgt') as any as {
|
||||||
__isFragment: true
|
__isFragment: true
|
||||||
|
@ -617,9 +617,7 @@ function _createVNode(
|
||||||
|
|
||||||
export function guardReactiveProps(props: (Data & VNodeProps) | null) {
|
export function guardReactiveProps(props: (Data & VNodeProps) | null) {
|
||||||
if (!props) return null
|
if (!props) return null
|
||||||
return isProxy(props) || Object.getPrototypeOf(props) === attrsProto
|
return isProxy(props) || isInternalObject(props) ? extend({}, props) : props
|
||||||
? extend({}, props)
|
|
||||||
: props
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cloneVNode<T, U>(
|
export function cloneVNode<T, U>(
|
||||||
|
@ -791,7 +789,7 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
|
||||||
} else {
|
} else {
|
||||||
type = ShapeFlags.SLOTS_CHILDREN
|
type = ShapeFlags.SLOTS_CHILDREN
|
||||||
const slotFlag = (children as RawSlots)._
|
const slotFlag = (children as RawSlots)._
|
||||||
if (!slotFlag) {
|
if (!slotFlag && !isInternalObject(children)) {
|
||||||
// if slots are not normalized, attach context instance
|
// if slots are not normalized, attach context instance
|
||||||
// (compiled / normalized slots already have context)
|
// (compiled / normalized slots already have context)
|
||||||
;(children as RawSlots)._ctx = currentRenderingInstance
|
;(children as RawSlots)._ctx = currentRenderingInstance
|
||||||
|
|
Loading…
Reference in New Issue