perf: use class for SetupContext

This commit is contained in:
Evan You 2024-12-01 17:00:38 +08:00
parent d6415d8442
commit 5828f2441f
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
1 changed files with 37 additions and 39 deletions

View File

@ -34,42 +34,25 @@ export type FunctionalComponent = SetupFn &
displayName?: string displayName?: string
} }
export type SetupContext<E = EmitsOptions> = E extends any export class SetupContext<E = EmitsOptions> {
? { attrs: Data
attrs: Data emit: EmitFn<E>
emit: EmitFn<E> slots: Readonly<StaticSlots>
expose: (exposed?: Record<string, any>) => void expose: (exposed?: Record<string, any>) => void
slots: Readonly<StaticSlots>
constructor(instance: ComponentInternalInstance) {
this.attrs = instance.attrs
this.emit = instance.emit as EmitFn<E>
this.slots = instance.slots
this.expose = (exposed = {}) => {
instance.exposed = exposed
} }
: never }
}
export function createSetupContext( export function createSetupContext(
instance: ComponentInternalInstance, instance: ComponentInternalInstance,
): SetupContext { ): SetupContext {
const expose: SetupContext['expose'] = exposed => {
if (__DEV__) {
if (instance.exposed) {
warn(`expose() should be called only once per setup().`)
}
if (exposed != null) {
let exposedType: string = typeof exposed
if (exposedType === 'object') {
if (isArray(exposed)) {
exposedType = 'array'
} else if (isRef(exposed)) {
exposedType = 'ref'
}
}
if (exposedType !== 'object') {
warn(
`expose() should be passed a plain object, received ${exposedType}.`,
)
}
}
}
instance.exposed = exposed || {}
}
if (__DEV__) { if (__DEV__) {
// We use getters in dev in case libs like test-utils overwrite instance // We use getters in dev in case libs like test-utils overwrite instance
// properties (overwrites should not be done in prod) // properties (overwrites should not be done in prod)
@ -83,15 +66,30 @@ export function createSetupContext(
get emit() { get emit() {
return (event: string, ...args: any[]) => instance.emit(event, ...args) return (event: string, ...args: any[]) => instance.emit(event, ...args)
}, },
expose, expose: (exposed?: Record<string, any>) => {
}) if (instance.exposed) {
warn(`expose() should be called only once per setup().`)
}
if (exposed != null) {
let exposedType: string = typeof exposed
if (exposedType === 'object') {
if (isArray(exposed)) {
exposedType = 'array'
} else if (isRef(exposed)) {
exposedType = 'ref'
}
}
if (exposedType !== 'object') {
warn(
`expose() should be passed a plain object, received ${exposedType}.`,
)
}
}
instance.exposed = exposed || {}
},
}) as SetupContext
} else { } else {
return { return new SetupContext(instance)
attrs: instance.attrs,
emit: instance.emit,
slots: instance.slots,
expose,
}
} }
} }