|
|
@@ -105,7 +105,7 @@ export interface ComponentInternalOptions {
|
|
|
export interface FunctionalComponent<P = {}, E extends EmitsOptions = {}>
|
|
|
extends ComponentInternalOptions {
|
|
|
// use of any here is intentional so it can be a valid JSX Element constructor
|
|
|
- (props: P, ctx: SetupContext<E, P>): any
|
|
|
+ (props: P, ctx: Omit<SetupContext<E, P>, 'expose'>): any
|
|
|
props?: ComponentPropsOptions<P>
|
|
|
emits?: E | (keyof E)[]
|
|
|
inheritAttrs?: boolean
|
|
|
@@ -172,6 +172,7 @@ export interface SetupContext<E = EmitsOptions, P = Data> {
|
|
|
attrs: Data
|
|
|
slots: Slots
|
|
|
emit: EmitFn<E>
|
|
|
+ expose: (exposed: Record<string, any>) => void
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -271,6 +272,9 @@ export interface ComponentInternalInstance {
|
|
|
// main proxy that serves as the public instance (`this`)
|
|
|
proxy: ComponentPublicInstance | null
|
|
|
|
|
|
+ // exposed properties via expose()
|
|
|
+ exposed: Record<string, any> | null
|
|
|
+
|
|
|
/**
|
|
|
* alternative proxy used only for runtime-compiled render functions using
|
|
|
* `with` block
|
|
|
@@ -416,6 +420,7 @@ export function createComponentInstance(
|
|
|
update: null!, // will be set synchronously right after creation
|
|
|
render: null,
|
|
|
proxy: null,
|
|
|
+ exposed: null,
|
|
|
withProxy: null,
|
|
|
effects: null,
|
|
|
provides: parent ? parent.provides : Object.create(appContext.provides),
|
|
|
@@ -732,6 +737,13 @@ const attrHandlers: ProxyHandler<Data> = {
|
|
|
}
|
|
|
|
|
|
function createSetupContext(instance: ComponentInternalInstance): SetupContext {
|
|
|
+ const expose: SetupContext['expose'] = exposed => {
|
|
|
+ if (__DEV__ && instance.exposed) {
|
|
|
+ warn(`expose() should be called only once per setup().`)
|
|
|
+ }
|
|
|
+ instance.exposed = proxyRefs(exposed)
|
|
|
+ }
|
|
|
+
|
|
|
if (__DEV__) {
|
|
|
// We use getters in dev in case libs like test-utils overwrite instance
|
|
|
// properties (overwrites should not be done in prod)
|
|
|
@@ -747,14 +759,16 @@ function createSetupContext(instance: ComponentInternalInstance): SetupContext {
|
|
|
},
|
|
|
get emit() {
|
|
|
return (event: string, ...args: any[]) => instance.emit(event, ...args)
|
|
|
- }
|
|
|
+ },
|
|
|
+ expose
|
|
|
})
|
|
|
} else {
|
|
|
return {
|
|
|
props: instance.props,
|
|
|
attrs: instance.attrs,
|
|
|
slots: instance.slots,
|
|
|
- emit: instance.emit
|
|
|
+ emit: instance.emit,
|
|
|
+ expose
|
|
|
}
|
|
|
}
|
|
|
}
|