From e09296085101b50f2792e9cf89c595ae89678f34 Mon Sep 17 00:00:00 2001 From: Austin Keener Date: Thu, 1 Jul 2021 16:32:58 -0400 Subject: [PATCH] fix(runtime): Addressed issue with $parent chain when using expose() The instances provided by $parent and $root when dealing with a $parent or $root that used the 'expose(...)' function would not return the ExposeProxy, thus no Vue public $ getters were accessible. --- packages/runtime-core/__tests__/apiExpose.spec.ts | 11 ++++++++++- packages/runtime-core/src/componentPublicInstance.ts | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) 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) }