feat(Form): support async validation

This commit is contained in:
陈嘉涵 2020-02-12 10:38:05 +08:00
parent 35260e024a
commit 080d1828c8
5 changed files with 120 additions and 46 deletions

View File

@ -3,7 +3,7 @@ import { formatNumber } from './utils';
import { isIOS } from '../utils/validate/system';
import { preventDefault } from '../utils/dom/event';
import { resetScroll } from '../utils/dom/reset-scroll';
import { createNamespace, isObject, isDef, addUnit } from '../utils';
import { createNamespace, isObject, isDef, addUnit, isPromise } from '../utils';
// Components
import Icon from '../icon';
@ -151,21 +151,30 @@ export default createComponent({
resolve();
}
const messages = [];
this.rules.forEach(rule => {
Promise.all(
this.rules.map(rule => {
if (rule.required && this.formValueEmpty) {
messages.push(rule.message);
return Promise.resolve(rule.message);
}
if (rule.validator) {
const result = rule.validator(this.formValue);
const returnVal = rule.validator(this.formValue);
if (!result) {
messages.push(rule.message);
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];
@ -177,6 +186,7 @@ export default createComponent({
resolve();
}
});
});
},
resetValidate() {

View File

@ -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
```html

View File

@ -60,17 +60,16 @@ export default {
### 校验规则
`rules`中,可以通过`validator`字段定义校验函数,校验函数返回`false`时表示校验不通过
`rules`中,可以通过`validator`字段定义校验函数,校验函数返回`false`时表示校验不通过,返回`Promise`时表示异步校验
```html
<van-form>
<van-form @submit="onSubmit" @failed="onFailed">
<van-field
v-model="value"
name="phone"
label="手机号"
:rules="rules"
placeholder="手机号"
@submit="onSubmit"
@failed="onFailed"
/>
<div style="margin: 16px;">
<van-button round block type="info">提交</van-button>

View File

@ -1,13 +1,19 @@
<template>
<demo-block :title="$t('title')">
<van-form>
<van-form validate-first @sumbit="onSubmit" @failed="onFailed">
<van-field
v-model="value"
v-model="phone"
name="phone"
:label="$t('phone')"
:rules="rules"
:rules="rules.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;">
<van-button type="info" round block>{{ $t('submit') }}</van-button>
@ -20,35 +26,57 @@
export default {
i18n: {
'zh-CN': {
code: '验证码',
phone: '手机号',
title: '校验规则',
submit: '提交',
required: '请输入手机号',
incorrectFormat: '手机号格式错误',
validating: '验证中...',
incorrectCode: '验证码错误',
incorrectPhone: '手机号格式错误',
},
'en-US': {
code: 'Code',
phone: 'Phone',
title: 'Validate Rules',
submit: 'Submit',
required: 'Phone is required',
incorrectFormat: 'Incorrect format',
validating: 'Validating...',
incorrectCode: 'Incorrect code',
incorrectPhone: 'Incorrect phone',
},
},
data() {
return {
value: '',
code: '',
phone: '',
};
},
created() {
this.rules = [
this.rules = {
phone: [
{ required: true, message: this.$t('required') },
{
validator: val => /1\d{10}/.test(val),
message: this.$t('incorrectFormat'),
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: {

View File

@ -76,14 +76,14 @@ test('raf', async () => {
cancelRaf(1);
});
test('is-email', () => {
test('isEmail', () => {
expect(isEmail('abc@gmail.com')).toBeTruthy();
expect(isEmail('abc@@gmail.com')).toBeFalsy();
expect(isEmail('@gmail.com')).toBeFalsy();
expect(isEmail('abc@')).toBeFalsy();
});
test('is-mobile', () => {
test('isMobile', () => {
expect(isMobile('13000000000')).toBeTruthy();
expect(isMobile('+8613000000000')).toBeTruthy();
expect(isMobile('8613000000000')).toBeTruthy();
@ -91,7 +91,7 @@ test('is-mobile', () => {
expect(isMobile('abc')).toBeFalsy();
});
test('is-number', () => {
test('isNumeric', () => {
expect(isNumeric('1')).toBeTruthy();
expect(isNumeric('1.2')).toBeTruthy();
expect(isNumeric('1..2')).toBeFalsy();