From: Evan You Date: Tue, 10 Dec 2024 09:00:35 +0000 (+0800) Subject: test(vapor): api expose (partial) X-Git-Tag: v3.6.0-alpha.1~16^2~172 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12ef12105b8c7bbdc8069575cf1bfaf82519480d;p=thirdparty%2Fvuejs%2Fcore.git test(vapor): api expose (partial) --- diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index db717f84e9..f91af6c739 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -380,16 +380,13 @@ export interface GenericComponentInstance { // exposed properties via expose() exposed: Record | null + exposeProxy: Record | null /** * setup related * @internal */ setupState?: Data - /** - * @internal - */ - setupContext?: any /** * devtools access to additional info * @internal @@ -603,6 +600,10 @@ export interface ComponentInternalInstance extends GenericComponentInstance { * @internal */ setupState: Data + /** + * @internal + */ + setupContext?: SetupContext | null // main proxy that serves as the public instance (`this`) proxy: ComponentPublicInstance | null @@ -1131,30 +1132,6 @@ function getSlotsProxy(instance: ComponentInternalInstance): Slots { export function createSetupContext( instance: ComponentInternalInstance, ): 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__) { // We use getters in dev in case libs like test-utils overwrite instance // properties (overwrites should not be done in prod) @@ -1173,46 +1150,69 @@ export function createSetupContext( get emit() { return (event: string, ...args: any[]) => instance.emit(event, ...args) }, - expose, + expose: exposed => expose(instance, exposed as any), }) } else { return { attrs: new Proxy(instance.attrs, attrsProxyHandlers), slots: instance.slots, emit: instance.emit, - expose, + expose: exposed => expose(instance, exposed as any), } } } -export function getComponentPublicInstance( +/** + * @internal + */ +export function expose( instance: GenericComponentInstance, + exposed: Record, +): void { + 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 || {} +} + +export function getComponentPublicInstance( + instance: ComponentInternalInstance, ): ComponentPublicInstance | ComponentInternalInstance['exposed'] | null { if (instance.exposed) { - if ('exposeProxy' in instance) { - return ( - instance.exposeProxy || - (instance.exposeProxy = new Proxy( - proxyRefs(markRaw(instance.exposed)), - { - get(target, key: string) { - if (key in target) { - return target[key] - } else if (key in publicPropertiesMap) { - return publicPropertiesMap[key]( - instance as ComponentInternalInstance, - ) - } - }, - has(target, key: string) { - return key in target || key in publicPropertiesMap - }, - }, - )) - ) - } else { - return instance.exposed - } + return ( + instance.exposeProxy || + (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), { + get(target, key: string) { + if (key in target) { + return target[key] + } else if (key in publicPropertiesMap) { + return publicPropertiesMap[key]( + instance as ComponentInternalInstance, + ) + } + }, + has(target, key: string) { + return key in target || key in publicPropertiesMap + }, + })) + ) } else { return instance.proxy } diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 0a0313e1d7..d6a56d5876 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -499,6 +499,7 @@ export { type ComponentInternalOptions, type GenericComponentInstance, type LifecycleHook, + expose, nextUid, validateComponentName, } from './component' diff --git a/packages/runtime-vapor/__tests__/_utils.ts b/packages/runtime-vapor/__tests__/_utils.ts index 6d0f0ee11a..626764881d 100644 --- a/packages/runtime-vapor/__tests__/_utils.ts +++ b/packages/runtime-vapor/__tests__/_utils.ts @@ -6,7 +6,7 @@ import type { RawProps } from '../src/componentProps' export interface RenderContext { component: VaporComponent host: HTMLElement - instance: VaporComponentInstance | undefined + instance: Record | undefined app: App create: (props?: RawProps) => RenderContext mount: (container?: string | ParentNode) => RenderContext diff --git a/packages/runtime-vapor/__tests__/apiExpose.spec.ts b/packages/runtime-vapor/__tests__/apiExpose.spec.ts index 91f2b76afa..8431d2c07f 100644 --- a/packages/runtime-vapor/__tests__/apiExpose.spec.ts +++ b/packages/runtime-vapor/__tests__/apiExpose.spec.ts @@ -6,25 +6,22 @@ import { currentInstance } from '@vue/runtime-dom' import { defineVaporComponent } from '../src/apiDefineComponent' const define = makeRender() -describe.todo('api: expose', () => { - test('via setup context', () => { + +describe('api: expose', () => { + test.todo('via setup context + template ref', () => { const Child = defineVaporComponent({ setup(_, { expose }) { expose({ foo: 1, bar: ref(2), }) - return { - bar: ref(3), - baz: ref(4), - } + return [] }, }) const childRef = ref() define({ render: () => { const n0 = createComponent(Child) - setRef(n0, childRef) return n0 }, }).render() @@ -35,7 +32,7 @@ describe.todo('api: expose', () => { expect(childRef.value.baz).toBeUndefined() }) - test('via setup context (expose empty)', () => { + test.todo('via setup context + template ref (expose empty)', () => { let childInstance: VaporComponentInstance | null = null const Child = defineVaporComponent({ setup(_) { @@ -62,13 +59,11 @@ describe.todo('api: expose', () => { expose({ foo: 1, }) - return { - bar: 2, - } + return [] }, }).render() - expect(instance!.exposed!.foo).toBe(1) - expect(instance!.exposed!.bar).toBe(undefined) + expect(instance!.foo).toBe(1) + expect(instance!.bar).toBe(undefined) }) test('warning for ref', () => { diff --git a/packages/runtime-vapor/__tests__/apiSetupHelpers.spec.ts b/packages/runtime-vapor/__tests__/apiSetupHelpers.spec.ts index 42c7c3e060..d4f7404487 100644 --- a/packages/runtime-vapor/__tests__/apiSetupHelpers.spec.ts +++ b/packages/runtime-vapor/__tests__/apiSetupHelpers.spec.ts @@ -1,13 +1,7 @@ -import type { SetupContext } from '../src/component' -import { - createComponent, - defineComponent, - ref, - template, - useAttrs, - useSlots, -} from '../src' +import { createComponent, defineVaporComponent, template } from '../src' +import { ref, useAttrs, useSlots } from '@vue/runtime-dom' import { makeRender } from './_utils' +import type { VaporComponentInstance } from '../src/component' const define = makeRender() @@ -15,15 +9,17 @@ describe.todo('SFC