Jelajahi Sumber

fix: getFieldComponentRef will return actual ref within AsyncComponentWrapper (#6252)

修复异步加载组件时,表单的getFieldComponentRef方法没能获取到正确的组件实例
Netfan 4 bulan lalu
induk
melakukan
0c3edb10b0

+ 20 - 3
packages/@core/ui-kit/form-ui/src/form-api.ts

@@ -11,7 +11,7 @@ import type { Recordable } from '@vben-core/typings';
 
 import type { FormActions, FormSchema, VbenFormProps } from './types';
 
-import { toRaw } from 'vue';
+import { isRef, toRaw } from 'vue';
 
 import { Store } from '@vben-core/shared/store';
 import {
@@ -100,9 +100,26 @@ export class FormApi {
   getFieldComponentRef<T = ComponentPublicInstance>(
     fieldName: string,
   ): T | undefined {
-    return this.componentRefMap.has(fieldName)
-      ? (this.componentRefMap.get(fieldName) as T)
+    let target = this.componentRefMap.has(fieldName)
+      ? (this.componentRefMap.get(fieldName) as ComponentPublicInstance)
       : undefined;
+    if (
+      target &&
+      target.$.type.name === 'AsyncComponentWrapper' &&
+      target.$.subTree.ref
+    ) {
+      if (Array.isArray(target.$.subTree.ref)) {
+        if (
+          target.$.subTree.ref.length > 0 &&
+          isRef(target.$.subTree.ref[0]?.r)
+        ) {
+          target = target.$.subTree.ref[0]?.r.value as ComponentPublicInstance;
+        }
+      } else if (isRef(target.$.subTree.ref.r)) {
+        target = target.$.subTree.ref.r.value as ComponentPublicInstance;
+      }
+    }
+    return target as T;
   }
 
   /**

+ 1 - 1
playground/src/views/examples/form/api.vue

@@ -134,7 +134,7 @@ function handleClick(
     }
     case 'componentRef': {
       // 获取下拉组件的实例,并调用它的focus方法
-      formApi.getFieldComponentRef<RefSelectProps>('fieldOptions')?.focus();
+      formApi.getFieldComponentRef<RefSelectProps>('fieldOptions')?.focus?.();
       break;
     }
     case 'disabled': {