chore: Merge branch 'feat/expose' into script-setup-2

This commit is contained in:
Evan You
2020-11-14 12:50:32 -05:00
8 changed files with 741 additions and 584 deletions

View File

@@ -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
}
}
}