2
0
Эх сурвалжийг харах

fix(runtime-vapor): properly set ref on dynamic component + vdom component (#14496)

Jack 1 сар өмнө
parent
commit
e05c850336

+ 34 - 0
packages/runtime-vapor/__tests__/vdomInterop.spec.ts

@@ -35,6 +35,7 @@ import {
   createDynamicComponent,
   createDynamicComponent,
   createIf,
   createIf,
   createSlot,
   createSlot,
+  createTemplateRefSetter,
   defineVaporAsyncComponent,
   defineVaporAsyncComponent,
   defineVaporComponent,
   defineVaporComponent,
   renderEffect,
   renderEffect,
@@ -733,6 +734,39 @@ describe('vdomInterop', () => {
       await nextTick()
       await nextTick()
       expect(html()).toBe('bar')
       expect(html()).toBe('bar')
     })
     })
+
+    it('dynamic component includes vdom component', async () => {
+      const VdomChild = defineComponent({
+        setup(_, { expose }) {
+          expose({ name: 'vdomChild' })
+          return () => h('div', 'vdom child')
+        },
+      })
+
+      const VaporChild = defineVaporComponent({
+        setup() {
+          return { vdomRef }
+        },
+        render() {
+          const setRef = createTemplateRefSetter()
+          const n0 = createDynamicComponent(() => VdomChild)
+          setRef(n0, vdomRef, false, 'vdomRef')
+          return n0
+        },
+      })
+
+      const vdomRef = ref<any>(null)
+
+      define({
+        setup() {
+          return () => h(VaporChild as any)
+        },
+      }).render()
+
+      await nextTick()
+      expect(vdomRef.value).toBeDefined()
+      expect(vdomRef.value.name).toBe('vdomChild')
+    })
   })
   })
 
 
   describe('dynamic component', () => {
   describe('dynamic component', () => {

+ 9 - 3
packages/runtime-vapor/src/apiTemplateRef.ts

@@ -107,10 +107,14 @@ function setRef(
   if (!instance || instance.isUnmounted) return
   if (!instance || instance.isUnmounted) return
 
 
   // vdom interop
   // vdom interop
-  if (isInteropEnabled && isFragment(el) && el.setRef) {
-    el.setRef(instance, ref, refFor, refKey)
-    return
+  const handleVdomRef = (target: any): boolean => {
+    if (isInteropEnabled && isFragment(target) && target.setRef) {
+      target.setRef(instance, ref, refFor, refKey)
+      return true
+    }
+    return false
   }
   }
+  if (handleVdomRef(el)) return ref
 
 
   if (isVaporComponent(el) && isAsyncWrapper(el)) {
   if (isVaporComponent(el) && isAsyncWrapper(el)) {
     // unresolved: handled in DynamicFragment's updated hook
     // unresolved: handled in DynamicFragment's updated hook
@@ -122,6 +126,8 @@ function setRef(
 
 
   const setupState: any = __DEV__ ? instance.setupState || {} : null
   const setupState: any = __DEV__ ? instance.setupState || {} : null
   const refValue = getRefValue(el)
   const refValue = getRefValue(el)
+  if (handleVdomRef(refValue)) return ref
+
   const refs =
   const refs =
     instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs
     instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs