Commit 5f735e8728ed14a8cd76dce9c347798c74cfe25d
1 parent
6a601e83
fix: 修复BasicForm组件进行表单验证时无法触发blur事件
Showing
5 changed files
with
28 additions
and
12 deletions
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | :formProps="getProps" |
17 | 17 | :allDefaultValues="defaultValueRef" |
18 | 18 | :formModel="formModel" |
19 | + :validateFields="validateFields" | |
19 | 20 | :setFormModel="setFormModel" |
20 | 21 | > |
21 | 22 | <template #[item]="data" v-for="item in Object.keys($slots)"> |
... | ... | @@ -229,10 +230,10 @@ |
229 | 230 | |
230 | 231 | function setFormModel(key: string, value: any) { |
231 | 232 | formModel[key] = value; |
232 | - const { validateTrigger } = unref(getBindValue); | |
233 | - if (!validateTrigger || validateTrigger === 'change') { | |
234 | - validateFields([key]).catch((_) => {}); | |
235 | - } | |
233 | + // const { validateTrigger } = unref(getBindValue); | |
234 | + // if (!validateTrigger || validateTrigger === 'change') { | |
235 | + // validateFields([key]).catch((_) => {}); | |
236 | + // } | |
236 | 237 | } |
237 | 238 | |
238 | 239 | function handleEnterPress(e: KeyboardEvent) { | ... | ... |
... | ... | @@ -14,6 +14,7 @@ |
14 | 14 | import { upperFirst, cloneDeep } from 'lodash-es'; |
15 | 15 | import { useItemLabelWidth } from '../hooks/useLabelWidth'; |
16 | 16 | import { useI18n } from '/@/hooks/web/useI18n'; |
17 | + import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface'; | |
17 | 18 | |
18 | 19 | export default defineComponent({ |
19 | 20 | name: 'BasicFormItem', |
... | ... | @@ -39,6 +40,12 @@ |
39 | 40 | type: Function as PropType<(key: string, value: any) => void>, |
40 | 41 | default: null, |
41 | 42 | }, |
43 | + validateFields: { | |
44 | + type: Function as PropType< | |
45 | + (nameList?: NamePath[], options?: ValidateOptions) => Promise<any> | |
46 | + >, | |
47 | + default: null, | |
48 | + }, | |
42 | 49 | tableAction: { |
43 | 50 | type: Object as PropType<TableActionType>, |
44 | 51 | }, |
... | ... | @@ -208,6 +215,7 @@ |
208 | 215 | rules[characterInx].message || |
209 | 216 | t('component.form.maxTip', [rules[characterInx].max] as Recordable); |
210 | 217 | } |
218 | + rules.forEach((item) => !item.trigger && (item.trigger = 'change')); | |
211 | 219 | return rules; |
212 | 220 | } |
213 | 221 | |
... | ... | @@ -234,6 +242,10 @@ |
234 | 242 | const value = target ? (isCheck ? target.checked : target.value) : e; |
235 | 243 | props.setFormModel(field, value); |
236 | 244 | }, |
245 | + onBlur: (...args) => { | |
246 | + unref(getComponentsProps)?.onBlur?.(...args); | |
247 | + props.validateFields([field], { triggerName: 'blur' }).catch((_) => {}); | |
248 | + }, | |
237 | 249 | }; |
238 | 250 | const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>; |
239 | 251 | ... | ... |
1 | 1 | import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form'; |
2 | -import type { NamePath } from 'ant-design-vue/lib/form/interface'; | |
2 | +import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface'; | |
3 | 3 | import type { DynamicProps } from '/#/utils'; |
4 | 4 | import { ref, onUnmounted, unref, nextTick, watch } from 'vue'; |
5 | 5 | import { isProdMode } from '/@/utils/env'; |
... | ... | @@ -112,9 +112,12 @@ export function useForm(props?: Props): UseFormReturnType { |
112 | 112 | return form.validate(nameList); |
113 | 113 | }, |
114 | 114 | |
115 | - validateFields: async (nameList?: NamePath[]): Promise<Recordable> => { | |
115 | + validateFields: async ( | |
116 | + nameList?: NamePath[], | |
117 | + options?: ValidateOptions | |
118 | + ): Promise<Recordable> => { | |
116 | 119 | const form = await getForm(); |
117 | - return form.validateFields(nameList); | |
120 | + return form.validateFields(nameList, options); | |
118 | 121 | }, |
119 | 122 | }; |
120 | 123 | ... | ... |
1 | 1 | import type { ComputedRef, Ref } from 'vue'; |
2 | 2 | import type { FormProps, FormSchema, FormActionType } from '../types/form'; |
3 | -import type { NamePath } from 'ant-design-vue/lib/form/interface'; | |
3 | +import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface'; | |
4 | 4 | import { unref, toRaw } from 'vue'; |
5 | 5 | import { isArray, isFunction, isObject, isString } from '/@/utils/is'; |
6 | 6 | import { deepMerge } from '/@/utils'; |
... | ... | @@ -206,8 +206,8 @@ export function useFormEvents({ |
206 | 206 | }); |
207 | 207 | } |
208 | 208 | |
209 | - async function validateFields(nameList?: NamePath[] | undefined) { | |
210 | - return unref(formElRef)?.validateFields(nameList); | |
209 | + async function validateFields(nameList?: NamePath[] | undefined, options?: ValidateOptions) { | |
210 | + return unref(formElRef)?.validateFields(nameList, options); | |
211 | 211 | } |
212 | 212 | |
213 | 213 | async function validate(nameList?: NamePath[] | undefined) { | ... | ... |
1 | -import type { NamePath, RuleObject } from 'ant-design-vue/lib/form/interface'; | |
1 | +import type { NamePath, RuleObject, ValidateOptions } from 'ant-design-vue/lib/form/interface'; | |
2 | 2 | import type { VNode } from 'vue'; |
3 | 3 | import type { ButtonProps as AntdButtonProps } from '/@/components/Button'; |
4 | 4 | import type { FormItem } from './formItem'; |
... | ... | @@ -39,7 +39,7 @@ export interface FormActionType { |
39 | 39 | prefixField: string | undefined, |
40 | 40 | first?: boolean | undefined |
41 | 41 | ) => Promise<void>; |
42 | - validateFields: (nameList?: NamePath[]) => Promise<any>; | |
42 | + validateFields: (nameList?: NamePath[], options?: ValidateOptions) => Promise<any>; | |
43 | 43 | validate: (nameList?: NamePath[]) => Promise<any>; |
44 | 44 | scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>; |
45 | 45 | } | ... | ... |