mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(Form): support setting multile validate-trigger (#10544)
This commit is contained in:
parent
c378f4ead1
commit
6baf42fa4a
@ -16,6 +16,7 @@ import {
|
|||||||
isDef,
|
isDef,
|
||||||
extend,
|
extend,
|
||||||
addUnit,
|
addUnit,
|
||||||
|
toArray,
|
||||||
FORM_KEY,
|
FORM_KEY,
|
||||||
numericProp,
|
numericProp,
|
||||||
unknownProp,
|
unknownProp,
|
||||||
@ -239,12 +240,12 @@ export default defineComponent({
|
|||||||
|
|
||||||
const validateWithTrigger = (trigger: FieldValidateTrigger) => {
|
const validateWithTrigger = (trigger: FieldValidateTrigger) => {
|
||||||
if (form && props.rules) {
|
if (form && props.rules) {
|
||||||
const defaultTrigger = form.props.validateTrigger === trigger;
|
const { validateTrigger } = form.props;
|
||||||
|
const defaultTrigger = toArray(validateTrigger).includes(trigger);
|
||||||
const rules = props.rules.filter((rule) => {
|
const rules = props.rules.filter((rule) => {
|
||||||
if (rule.trigger) {
|
if (rule.trigger) {
|
||||||
return rule.trigger === trigger;
|
return toArray(rule.trigger).includes(trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultTrigger;
|
return defaultTrigger;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export type FiledRuleFormatter = (value: any, rule: FieldRule) => string;
|
|||||||
|
|
||||||
export type FieldRule = {
|
export type FieldRule = {
|
||||||
pattern?: RegExp;
|
pattern?: RegExp;
|
||||||
trigger?: FieldValidateTrigger;
|
trigger?: FieldValidateTrigger | FieldValidateTrigger[];
|
||||||
message?: FieldRuleMessage;
|
message?: FieldRuleMessage;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
validator?: FieldRuleValidator;
|
validator?: FieldRuleValidator;
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
truthProp,
|
truthProp,
|
||||||
numericProp,
|
numericProp,
|
||||||
preventDefault,
|
preventDefault,
|
||||||
makeStringProp,
|
|
||||||
createNamespace,
|
createNamespace,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
@ -35,9 +34,14 @@ const formProps = {
|
|||||||
scrollToError: Boolean,
|
scrollToError: Boolean,
|
||||||
validateFirst: Boolean,
|
validateFirst: Boolean,
|
||||||
submitOnEnter: truthProp,
|
submitOnEnter: truthProp,
|
||||||
validateTrigger: makeStringProp<FieldValidateTrigger>('onBlur'),
|
|
||||||
showErrorMessage: truthProp,
|
showErrorMessage: truthProp,
|
||||||
errorMessageAlign: String as PropType<FieldTextAlign>,
|
errorMessageAlign: String as PropType<FieldTextAlign>,
|
||||||
|
validateTrigger: {
|
||||||
|
type: [String, Array] as PropType<
|
||||||
|
FieldValidateTrigger | FieldValidateTrigger[]
|
||||||
|
>,
|
||||||
|
default: 'onBlur',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FormProps = ExtractPropTypes<typeof formProps>;
|
export type FormProps = ExtractPropTypes<typeof formProps>;
|
||||||
|
@ -497,7 +497,7 @@ export default {
|
|||||||
| label-align | Field label align, can be set to `center` `right` | _string_ | `left` |
|
| label-align | Field label align, can be set to `center` `right` | _string_ | `left` |
|
||||||
| input-align | Field input align, can be set to `center` `right` | _string_ | `left` |
|
| input-align | Field input align, can be set to `center` `right` | _string_ | `left` |
|
||||||
| error-message-align | Error message align, can be set to `center` `right` | _string_ | `left` |
|
| error-message-align | Error message align, can be set to `center` `right` | _string_ | `left` |
|
||||||
| validate-trigger | When to validate the form, can be set to `onChange`、`onSubmit` | _string_ | `onBlur` |
|
| validate-trigger | When to validate the form, can be set to `onChange`、`onSubmit`, supports using array to set multiple values | _string \| string[]_ | `onBlur` |
|
||||||
| colon | Whether to display colon after label | _boolean_ | `false` |
|
| colon | Whether to display colon after label | _boolean_ | `false` |
|
||||||
| disabled | Whether to disable form | _boolean_ | `false` |
|
| disabled | Whether to disable form | _boolean_ | `false` |
|
||||||
| readonly | Whether to be readonly | _boolean_ | `false` |
|
| readonly | Whether to be readonly | _boolean_ | `false` |
|
||||||
|
@ -529,7 +529,7 @@ export default {
|
|||||||
| label-align | 表单项 label 对齐方式,可选值为 `center` `right` | _string_ | `left` |
|
| label-align | 表单项 label 对齐方式,可选值为 `center` `right` | _string_ | `left` |
|
||||||
| input-align | 输入框对齐方式,可选值为 `center` `right` | _string_ | `left` |
|
| input-align | 输入框对齐方式,可选值为 `center` `right` | _string_ | `left` |
|
||||||
| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | _string_ | `left` |
|
| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | _string_ | `left` |
|
||||||
| validate-trigger | 表单校验触发时机,可选值为 `onChange`、`onSubmit`,详见下表 | _string_ | `onBlur` |
|
| validate-trigger | 表单校验触发时机,可选值为 `onChange`、`onSubmit`,支持通过数组同时设置多个值,具体用法见下方表格 | _string \| string[]_ | `onBlur` |
|
||||||
| colon | 是否在 label 后面添加冒号 | _boolean_ | `false` |
|
| colon | 是否在 label 后面添加冒号 | _boolean_ | `false` |
|
||||||
| disabled | 是否禁用表单中的所有输入框 | _boolean_ | `false` |
|
| disabled | 是否禁用表单中的所有输入框 | _boolean_ | `false` |
|
||||||
| readonly | 是否将表单中的所有输入框设置为只读状态 | _boolean_ | `false` |
|
| readonly | 是否将表单中的所有输入框设置为只读状态 | _boolean_ | `false` |
|
||||||
|
@ -293,6 +293,43 @@ test('should trigger validate after inputting when validate-trigger prop is onCh
|
|||||||
expect(wrapper.find('.van-field__error-message').exists).toBeTruthy();
|
expect(wrapper.find('.van-field__error-message').exists).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should trigger validate correctly when validate-trigger prop is array', async () => {
|
||||||
|
const wrapper = mount({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
...getSimpleRules(),
|
||||||
|
value: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Form ref="form" validateTrigger={['onBlur', 'onChange']}>
|
||||||
|
<Field
|
||||||
|
v-model={this.value}
|
||||||
|
name="A"
|
||||||
|
rules={this.rulesA}
|
||||||
|
modelValue=""
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const input = wrapper.find('input');
|
||||||
|
|
||||||
|
await input.trigger('input');
|
||||||
|
expect(wrapper.find('.van-field__error-message').exists()).toBeFalsy();
|
||||||
|
|
||||||
|
await input.trigger('blur');
|
||||||
|
expect(wrapper.find('.van-field__error-message').exists()).toBeTruthy();
|
||||||
|
|
||||||
|
await wrapper.setData({ value: '1' });
|
||||||
|
expect(wrapper.find('.van-field__error-message').exists()).toBeFalsy();
|
||||||
|
|
||||||
|
await wrapper.setData({ value: '' });
|
||||||
|
expect(wrapper.find('.van-field__error-message').exists).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
test('should allow to custom trigger in rules', async () => {
|
test('should allow to custom trigger in rules', async () => {
|
||||||
const rulesA = [
|
const rulesA = [
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
pick,
|
pick,
|
||||||
extend,
|
extend,
|
||||||
|
toArray,
|
||||||
isPromise,
|
isPromise,
|
||||||
truthProp,
|
truthProp,
|
||||||
Interceptor,
|
Interceptor,
|
||||||
@ -24,7 +25,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
bem,
|
bem,
|
||||||
name,
|
name,
|
||||||
toArray,
|
|
||||||
isOversize,
|
isOversize,
|
||||||
filterFiles,
|
filterFiles,
|
||||||
isImageFile,
|
isImageFile,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createNamespace, isFunction } from '../utils';
|
import { toArray, createNamespace, isFunction } from '../utils';
|
||||||
import type {
|
import type {
|
||||||
UploaderMaxSize,
|
UploaderMaxSize,
|
||||||
UploaderResultType,
|
UploaderResultType,
|
||||||
@ -9,9 +9,6 @@ const [name, bem, t] = createNamespace('uploader');
|
|||||||
|
|
||||||
export { name, bem, t };
|
export { name, bem, t };
|
||||||
|
|
||||||
export const toArray = <T>(item: T | T[]): T[] =>
|
|
||||||
Array.isArray(item) ? item : [item];
|
|
||||||
|
|
||||||
export function readFileContent(file: File, resultType: UploaderResultType) {
|
export function readFileContent(file: File, resultType: UploaderResultType) {
|
||||||
return new Promise<string | void>((resolve) => {
|
return new Promise<string | void>((resolve) => {
|
||||||
if (resultType === 'file') {
|
if (resultType === 'file') {
|
||||||
|
@ -36,3 +36,6 @@ export function pick<T, U extends keyof T>(
|
|||||||
return ret;
|
return ret;
|
||||||
}, {} as Writeable<Pick<T, U>>);
|
}, {} as Writeable<Pick<T, U>>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const toArray = <T>(item: T | T[]): T[] =>
|
||||||
|
Array.isArray(item) ? item : [item];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user