mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(Form): support async validation
This commit is contained in:
parent
35260e024a
commit
080d1828c8
@ -3,7 +3,7 @@ import { formatNumber } from './utils';
|
|||||||
import { isIOS } from '../utils/validate/system';
|
import { isIOS } from '../utils/validate/system';
|
||||||
import { preventDefault } from '../utils/dom/event';
|
import { preventDefault } from '../utils/dom/event';
|
||||||
import { resetScroll } from '../utils/dom/reset-scroll';
|
import { resetScroll } from '../utils/dom/reset-scroll';
|
||||||
import { createNamespace, isObject, isDef, addUnit } from '../utils';
|
import { createNamespace, isObject, isDef, addUnit, isPromise } from '../utils';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
@ -151,31 +151,41 @@ export default createComponent({
|
|||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = [];
|
Promise.all(
|
||||||
|
this.rules.map(rule => {
|
||||||
this.rules.forEach(rule => {
|
if (rule.required && this.formValueEmpty) {
|
||||||
if (rule.required && this.formValueEmpty) {
|
return Promise.resolve(rule.message);
|
||||||
messages.push(rule.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rule.validator) {
|
|
||||||
const result = rule.validator(this.formValue);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
messages.push(rule.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rule.validator) {
|
||||||
|
const returnVal = rule.validator(this.formValue);
|
||||||
|
|
||||||
|
if (returnVal === false) {
|
||||||
|
return Promise.resolve(rule.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPromise(returnVal)) {
|
||||||
|
return returnVal.then(
|
||||||
|
result => result === false && rule.message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
})
|
||||||
|
).then(messages => {
|
||||||
|
messages = messages.filter(item => item);
|
||||||
|
|
||||||
|
if (messages.length) {
|
||||||
|
this.validateMessage = messages[0];
|
||||||
|
resolve({
|
||||||
|
name: this.name,
|
||||||
|
messages,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (messages.length) {
|
|
||||||
this.validateMessage = messages[0];
|
|
||||||
resolve({
|
|
||||||
name: this.name,
|
|
||||||
messages,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -52,6 +52,43 @@ export default {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Validate Rules
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-form @submit="onSubmit" @failed="onFailed">
|
||||||
|
<van-field
|
||||||
|
v-model="value"
|
||||||
|
name="phone"
|
||||||
|
label="Phone"
|
||||||
|
:rules="rules"
|
||||||
|
placeholder="Phone"
|
||||||
|
/>
|
||||||
|
<div style="margin: 16px;">
|
||||||
|
<van-button round block type="info">Submit</van-button>
|
||||||
|
</div>
|
||||||
|
</van-form>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
this.rules = [
|
||||||
|
{ required: true, message: 'Phone is required' },
|
||||||
|
{ validator: val => /1\d{10}/.test(val), message: 'Incorrect format' },
|
||||||
|
];
|
||||||
|
return { value: '' };
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit(values) {
|
||||||
|
console.log('submit', values);
|
||||||
|
},
|
||||||
|
onFailed(errorInfo) {
|
||||||
|
console.log('failed', errorInfo);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### Field Type - Switch
|
### Field Type - Switch
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
@ -60,17 +60,16 @@ export default {
|
|||||||
|
|
||||||
### 校验规则
|
### 校验规则
|
||||||
|
|
||||||
在`rules`中,可以通过`validator`字段定义校验函数,校验函数返回`false`时表示校验不通过
|
在`rules`中,可以通过`validator`字段定义校验函数,校验函数返回`false`时表示校验不通过,返回`Promise`时表示异步校验
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-form>
|
<van-form @submit="onSubmit" @failed="onFailed">
|
||||||
<van-field
|
<van-field
|
||||||
v-model="value"
|
v-model="value"
|
||||||
|
name="phone"
|
||||||
label="手机号"
|
label="手机号"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
placeholder="手机号"
|
placeholder="手机号"
|
||||||
@submit="onSubmit"
|
|
||||||
@failed="onFailed"
|
|
||||||
/>
|
/>
|
||||||
<div style="margin: 16px;">
|
<div style="margin: 16px;">
|
||||||
<van-button round block type="info">提交</van-button>
|
<van-button round block type="info">提交</van-button>
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<demo-block :title="$t('title')">
|
<demo-block :title="$t('title')">
|
||||||
<van-form>
|
<van-form validate-first @sumbit="onSubmit" @failed="onFailed">
|
||||||
<van-field
|
<van-field
|
||||||
v-model="value"
|
v-model="phone"
|
||||||
|
name="phone"
|
||||||
:label="$t('phone')"
|
:label="$t('phone')"
|
||||||
:rules="rules"
|
:rules="rules.phone"
|
||||||
:placeholder="$t('phone')"
|
:placeholder="$t('phone')"
|
||||||
@submit="onSubmit"
|
/>
|
||||||
@failed="onFailed"
|
<van-field
|
||||||
|
v-model="code"
|
||||||
|
name="code"
|
||||||
|
:label="$t('code')"
|
||||||
|
:rules="rules.code"
|
||||||
|
:placeholder="$t('code')"
|
||||||
/>
|
/>
|
||||||
<div style="margin: 16px 16px 0;">
|
<div style="margin: 16px 16px 0;">
|
||||||
<van-button type="info" round block>{{ $t('submit') }}</van-button>
|
<van-button type="info" round block>{{ $t('submit') }}</van-button>
|
||||||
@ -20,35 +26,57 @@
|
|||||||
export default {
|
export default {
|
||||||
i18n: {
|
i18n: {
|
||||||
'zh-CN': {
|
'zh-CN': {
|
||||||
|
code: '验证码',
|
||||||
phone: '手机号',
|
phone: '手机号',
|
||||||
title: '校验规则',
|
title: '校验规则',
|
||||||
submit: '提交',
|
submit: '提交',
|
||||||
required: '请输入手机号',
|
required: '请输入手机号',
|
||||||
incorrectFormat: '手机号格式错误',
|
validating: '验证中...',
|
||||||
|
incorrectCode: '验证码错误',
|
||||||
|
incorrectPhone: '手机号格式错误',
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
|
code: 'Code',
|
||||||
phone: 'Phone',
|
phone: 'Phone',
|
||||||
title: 'Validate Rules',
|
title: 'Validate Rules',
|
||||||
submit: 'Submit',
|
submit: 'Submit',
|
||||||
required: 'Phone is required',
|
validating: 'Validating...',
|
||||||
incorrectFormat: 'Incorrect format',
|
incorrectCode: 'Incorrect code',
|
||||||
|
incorrectPhone: 'Incorrect phone',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
value: '',
|
code: '',
|
||||||
|
phone: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.rules = [
|
this.rules = {
|
||||||
{ required: true, message: this.$t('required') },
|
phone: [
|
||||||
{
|
{ required: true, message: this.$t('required') },
|
||||||
validator: val => /1\d{10}/.test(val),
|
{
|
||||||
message: this.$t('incorrectFormat'),
|
validator: val => /1\d{10}/.test(val),
|
||||||
},
|
message: this.$t('incorrectPhone'),
|
||||||
];
|
},
|
||||||
|
],
|
||||||
|
code: [
|
||||||
|
{
|
||||||
|
validator: val =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
this.$toast.loading(this.$t('validating'));
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$toast.clear();
|
||||||
|
resolve(/\d{6}/.test(val));
|
||||||
|
}, 1000);
|
||||||
|
}),
|
||||||
|
message: this.$t('incorrectCode'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -76,14 +76,14 @@ test('raf', async () => {
|
|||||||
cancelRaf(1);
|
cancelRaf(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is-email', () => {
|
test('isEmail', () => {
|
||||||
expect(isEmail('abc@gmail.com')).toBeTruthy();
|
expect(isEmail('abc@gmail.com')).toBeTruthy();
|
||||||
expect(isEmail('abc@@gmail.com')).toBeFalsy();
|
expect(isEmail('abc@@gmail.com')).toBeFalsy();
|
||||||
expect(isEmail('@gmail.com')).toBeFalsy();
|
expect(isEmail('@gmail.com')).toBeFalsy();
|
||||||
expect(isEmail('abc@')).toBeFalsy();
|
expect(isEmail('abc@')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is-mobile', () => {
|
test('isMobile', () => {
|
||||||
expect(isMobile('13000000000')).toBeTruthy();
|
expect(isMobile('13000000000')).toBeTruthy();
|
||||||
expect(isMobile('+8613000000000')).toBeTruthy();
|
expect(isMobile('+8613000000000')).toBeTruthy();
|
||||||
expect(isMobile('8613000000000')).toBeTruthy();
|
expect(isMobile('8613000000000')).toBeTruthy();
|
||||||
@ -91,7 +91,7 @@ test('is-mobile', () => {
|
|||||||
expect(isMobile('abc')).toBeFalsy();
|
expect(isMobile('abc')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is-number', () => {
|
test('isNumeric', () => {
|
||||||
expect(isNumeric('1')).toBeTruthy();
|
expect(isNumeric('1')).toBeTruthy();
|
||||||
expect(isNumeric('1.2')).toBeTruthy();
|
expect(isNumeric('1.2')).toBeTruthy();
|
||||||
expect(isNumeric('1..2')).toBeFalsy();
|
expect(isNumeric('1..2')).toBeFalsy();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user