Commit 3de5b53bcda5999a395e1f3fdcfd9e08c145f3ba

Authored by lzdjack
Committed by GitHub
1 parent d7f5dfeb

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

1.优化验证
2.修复自定义组件验证出错的问题
src/components/Form/src/BasicForm.vue
... ... @@ -64,7 +64,6 @@
64 64 import { basicProps } from './props';
65 65 import { useDesign } from '/@/hooks/web/useDesign';
66 66 import { cloneDeep } from 'lodash-es';
67   - import { isFunction, isArray } from '/@/utils/is';
68 67  
69 68 export default defineComponent({
70 69 name: 'BasicForm',
... ... @@ -245,14 +244,11 @@
245 244  
246 245 function setFormModel(key: string, value: any, schema: FormSchema) {
247 246 formModel[key] = value;
248   - const { validateTrigger } = unref(getBindValue);
249   - if (isFunction(schema.dynamicRules) || isArray(schema.rules)) {
250   - return;
251   - }
252   - if (!validateTrigger || validateTrigger === 'change') {
  247 + emit('field-value-change', key, value);
  248 + // TODO 优化验证,这里如果是autoLink=false手动关联的情况下才会再次触发此函数
  249 + if (schema && schema.itemProps && !schema.itemProps.autoLink) {
253 250 validateFields([key]).catch((_) => {});
254 251 }
255   - emit('field-value-change', key, value);
256 252 }
257 253  
258 254 function handleEnterPress(e: KeyboardEvent) {
... ...
src/components/Form/src/components/FormItem.vue
... ... @@ -9,7 +9,11 @@
9 9 import { BasicHelp } from '/@/components/Basic';
10 10 import { isBoolean, isFunction, isNull } from '/@/utils/is';
11 11 import { getSlot } from '/@/utils/helper/tsxHelper';
12   - import { createPlaceholderMessage, setComponentRuleType } from '../helper';
  12 + import {
  13 + createPlaceholderMessage,
  14 + NO_AUTO_LINK_COMPONENTS,
  15 + setComponentRuleType,
  16 + } from '../helper';
13 17 import { cloneDeep, upperFirst } from 'lodash-es';
14 18 import { useItemLabelWidth } from '../hooks/useLabelWidth';
15 19 import { useI18n } from '/@/hooks/web/useI18n';
... ... @@ -347,6 +351,15 @@
347 351 const showSuffix = !!suffix;
348 352 const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
349 353  
  354 + // TODO 自定义组件验证会出现问题,因此这里框架默认将自定义组件设置手动触发验证,如果其他组件还有此问题请手动设置autoLink=false
  355 + if (NO_AUTO_LINK_COMPONENTS.includes(component)) {
  356 + props.schema &&
  357 + (props.schema.itemProps! = {
  358 + autoLink: false,
  359 + ...props.schema.itemProps,
  360 + });
  361 + }
  362 +
350 363 return (
351 364 <Form.Item
352 365 name={field}
... ...
src/components/Form/src/helper.ts
... ... @@ -72,3 +72,16 @@ export function handleInputNumberValue(component?: ComponentType, val?: any) {
72 72 export const dateItemType = genType();
73 73  
74 74 export const defaultValueComponents = ['Input', 'InputPassword', 'InputSearch', 'InputTextArea'];
  75 +
  76 +// TODO 自定义组件封装会出现验证问题,因此这里目前改成手动触发验证
  77 +export const NO_AUTO_LINK_COMPONENTS: ComponentType[] = [
  78 + 'Upload',
  79 + 'ApiTransfer',
  80 + 'ApiTree',
  81 + 'ApiSelect',
  82 + 'ApiTreeSelect',
  83 + 'ApiRadioGroup',
  84 + 'ApiCascader',
  85 + 'AutoComplete',
  86 + 'RadioButtonGroup',
  87 +];
... ...
src/hooks/component/useFormItem.ts
... ... @@ -41,9 +41,7 @@ export function useRuleFormItem&lt;T extends Recordable&gt;(
41 41 if (isEqual(value, defaultState.value)) return;
42 42  
43 43 innerState.value = value as T[keyof T];
44   - setTimeout(() => {
45   - emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
46   - });
  44 + emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
47 45 },
48 46 });
49 47  
... ...
src/views/demo/form/index.vue
... ... @@ -68,6 +68,7 @@
68 68 import { Select } from 'ant-design-vue';
69 69 import { cloneDeep } from 'lodash-es';
70 70 import { areaRecord } from '/@/api/demo/cascader';
  71 + import { uploadApi } from '/@/api/sys/upload';
71 72  
72 73 const valueSelectA = ref<string[]>([]);
73 74 const valueSelectB = ref<string[]>([]);
... ... @@ -190,6 +191,18 @@
190 191 suffix: '天',
191 192 },
192 193 {
  194 + field: 'fieldsc',
  195 + component: 'Upload',
  196 + label: '上传',
  197 + colProps: {
  198 + span: 8,
  199 + },
  200 + rules: [{ required: true, message: '请选择上传文件' }],
  201 + componentProps: {
  202 + api: uploadApi,
  203 + },
  204 + },
  205 + {
193 206 field: 'field3',
194 207 component: 'DatePicker',
195 208 label: '字段3',
... ...