Commit 3de5b53bcda5999a395e1f3fdcfd9e08c145f3ba
Committed by
GitHub
1 parent
d7f5dfeb
fix: 修复表单验证 (#2620)
1.优化验证 2.修复自定义组件验证出错的问题
Showing
5 changed files
with
44 additions
and
11 deletions
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<T extends Recordable>( |
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', | ... | ... |