Jelajahi Sumber

fix: 修复表单验证 (#2620)

1.优化验证
2.修复自定义组件验证出错的问题
lzdjack 2 tahun lalu
induk
melakukan
3de5b53bcd

+ 3 - 7
src/components/Form/src/BasicForm.vue

@@ -64,7 +64,6 @@
   import { basicProps } from './props';
   import { useDesign } from '/@/hooks/web/useDesign';
   import { cloneDeep } from 'lodash-es';
-  import { isFunction, isArray } from '/@/utils/is';
 
   export default defineComponent({
     name: 'BasicForm',
@@ -245,14 +244,11 @@
 
       function setFormModel(key: string, value: any, schema: FormSchema) {
         formModel[key] = value;
-        const { validateTrigger } = unref(getBindValue);
-        if (isFunction(schema.dynamicRules) || isArray(schema.rules)) {
-          return;
-        }
-        if (!validateTrigger || validateTrigger === 'change') {
+        emit('field-value-change', key, value);
+        // TODO 优化验证,这里如果是autoLink=false手动关联的情况下才会再次触发此函数
+        if (schema && schema.itemProps && !schema.itemProps.autoLink) {
           validateFields([key]).catch((_) => {});
         }
-        emit('field-value-change', key, value);
       }
 
       function handleEnterPress(e: KeyboardEvent) {

+ 14 - 1
src/components/Form/src/components/FormItem.vue

@@ -9,7 +9,11 @@
   import { BasicHelp } from '/@/components/Basic';
   import { isBoolean, isFunction, isNull } from '/@/utils/is';
   import { getSlot } from '/@/utils/helper/tsxHelper';
-  import { createPlaceholderMessage, setComponentRuleType } from '../helper';
+  import {
+    createPlaceholderMessage,
+    NO_AUTO_LINK_COMPONENTS,
+    setComponentRuleType,
+  } from '../helper';
   import { cloneDeep, upperFirst } from 'lodash-es';
   import { useItemLabelWidth } from '../hooks/useLabelWidth';
   import { useI18n } from '/@/hooks/web/useI18n';
@@ -347,6 +351,15 @@
           const showSuffix = !!suffix;
           const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
 
+          // TODO 自定义组件验证会出现问题,因此这里框架默认将自定义组件设置手动触发验证,如果其他组件还有此问题请手动设置autoLink=false
+          if (NO_AUTO_LINK_COMPONENTS.includes(component)) {
+            props.schema &&
+              (props.schema.itemProps! = {
+                autoLink: false,
+                ...props.schema.itemProps,
+              });
+          }
+
           return (
             <Form.Item
               name={field}

+ 13 - 0
src/components/Form/src/helper.ts

@@ -72,3 +72,16 @@ export function handleInputNumberValue(component?: ComponentType, val?: any) {
 export const dateItemType = genType();
 
 export const defaultValueComponents = ['Input', 'InputPassword', 'InputSearch', 'InputTextArea'];
+
+// TODO 自定义组件封装会出现验证问题,因此这里目前改成手动触发验证
+export const NO_AUTO_LINK_COMPONENTS: ComponentType[] = [
+  'Upload',
+  'ApiTransfer',
+  'ApiTree',
+  'ApiSelect',
+  'ApiTreeSelect',
+  'ApiRadioGroup',
+  'ApiCascader',
+  'AutoComplete',
+  'RadioButtonGroup',
+];

+ 1 - 3
src/hooks/component/useFormItem.ts

@@ -41,9 +41,7 @@ export function useRuleFormItem<T extends Recordable>(
       if (isEqual(value, defaultState.value)) return;
 
       innerState.value = value as T[keyof T];
-      setTimeout(() => {
-        emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
-      });
+      emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
     },
   });
 

+ 13 - 0
src/views/demo/form/index.vue

@@ -68,6 +68,7 @@
   import { Select } from 'ant-design-vue';
   import { cloneDeep } from 'lodash-es';
   import { areaRecord } from '/@/api/demo/cascader';
+  import { uploadApi } from '/@/api/sys/upload';
 
   const valueSelectA = ref<string[]>([]);
   const valueSelectB = ref<string[]>([]);
@@ -190,6 +191,18 @@
       suffix: '天',
     },
     {
+      field: 'fieldsc',
+      component: 'Upload',
+      label: '上传',
+      colProps: {
+        span: 8,
+      },
+      rules: [{ required: true, message: '请选择上传文件' }],
+      componentProps: {
+        api: uploadApi,
+      },
+    },
+    {
       field: 'field3',
       component: 'DatePicker',
       label: '字段3',