Jelajahi Sumber

fix(runtime-core): fix instance accessed via $parent chain when using expose() (#4048)

Austin Keener 4 tahun lalu
induk
melakukan
12cf9f4ea1

+ 10 - 1
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)
   })
 })

+ 2 - 1
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)
 }