diff --git a/packages/runtime-core/__tests__/apiExpose.spec.ts b/packages/runtime-core/__tests__/apiExpose.spec.ts index fb957b68db3..9f7ba535031 100644 --- a/packages/runtime-core/__tests__/apiExpose.spec.ts +++ b/packages/runtime-core/__tests__/apiExpose.spec.ts @@ -171,13 +171,20 @@ describe('api: expose', () => { }) test('expose should allow access to built-in instance properties', () => { + const GrandChild = defineComponent({ + render() { + return h('div') + } + }) + + const grandChildRef = ref() const Child = defineComponent({ render() { return h('div') }, setup(_, { expose }) { expose() - return {} + return () => h(GrandChild, { ref: grandChildRef }) } }) @@ -190,5 +197,7 @@ describe('api: expose', () => { const root = nodeOps.createElement('div') render(h(Parent), root) expect(childRef.value.$el.tag).toBe('div') + expect(grandChildRef.value.$parent).toBe(childRef.value) + expect(grandChildRef.value.$parent.$parent).toBe(grandChildRef.value.$root) }) }) diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 9206b974ba4..7240120e5b7 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -1,6 +1,7 @@ import { ComponentInternalInstance, Data, + getExposeProxy, isStatefulComponent } from './component' import { nextTick, queueJob } from './scheduler' @@ -217,7 +218,7 @@ const getPublicInstance = ( i: ComponentInternalInstance | null ): ComponentPublicInstance | ComponentInternalInstance['exposed'] | null => { if (!i) return null - if (isStatefulComponent(i)) return i.exposed ? i.exposed : i.proxy + if (isStatefulComponent(i)) return getExposeProxy(i) || i.proxy return getPublicInstance(i.parent) }