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,20 +34,39 @@ 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>
expose: (exposed?: Record<string, any>) => void
slots: Readonly<StaticSlots> slots: Readonly<StaticSlots>
expose: (exposed?: Record<string, any>) => void
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 (__DEV__) {
// We use getters in dev in case libs like test-utils overwrite instance
// properties (overwrites should not be done in prod)
return Object.freeze({
get attrs() {
return getAttrsProxy(instance)
},
get slots() {
return getSlotsProxy(instance)
},
get emit() {
return (event: string, ...args: any[]) => instance.emit(event, ...args)
},
expose: (exposed?: Record<string, any>) => {
if (instance.exposed) { if (instance.exposed) {
warn(`expose() should be called only once per setup().`) warn(`expose() should be called only once per setup().`)
} }
@ -66,32 +85,11 @@ export function createSetupContext(
) )
} }
} }
}
instance.exposed = exposed || {} instance.exposed = exposed || {}
}
if (__DEV__) {
// We use getters in dev in case libs like test-utils overwrite instance
// properties (overwrites should not be done in prod)
return Object.freeze({
get attrs() {
return getAttrsProxy(instance)
}, },
get slots() { }) as SetupContext
return getSlotsProxy(instance)
},
get emit() {
return (event: string, ...args: any[]) => instance.emit(event, ...args)
},
expose,
})
} else { } else {
return { return new SetupContext(instance)
attrs: instance.attrs,
emit: instance.emit,
slots: instance.slots,
expose,
}
} }
} }