feat(Form): add validate-trigger prop

This commit is contained in:
陈嘉涵 2020-02-19 17:25:30 +08:00
parent 7154afb36f
commit c08db724a3
6 changed files with 89 additions and 9 deletions

View File

@ -64,6 +64,7 @@ export default createComponent({
watch: {
value() {
this.resetValidation();
this.validateWithTrigger('onChange');
this.$nextTick(this.adjustSize);
},
},
@ -158,8 +159,8 @@ export default createComponent({
});
},
runRules() {
return this.rules.reduce(
runRules(rules) {
return rules.reduce(
(promise, rule) =>
promise.then(() => {
if (this.validateMessage) {
@ -183,13 +184,13 @@ export default createComponent({
);
},
validate() {
validate(rules = this.rules) {
return new Promise(resolve => {
if (!this.rules) {
if (!rules) {
resolve();
}
this.runRules().then(() => {
this.runRules(rules).then(() => {
if (this.validateMessage) {
resolve({
name: this.name,
@ -202,6 +203,21 @@ export default createComponent({
});
},
validateWithTrigger(trigger) {
if (this.vanForm && this.rules) {
const defaultTrigger = this.vanForm.validateTrigger === trigger;
const rules = this.rules.filter(rule => {
if (rule.trigger) {
return rule.trigger === trigger;
}
return defaultTrigger;
});
this.validate(rules);
}
},
resetValidation() {
if (this.validateMessage) {
this.validateMessage = '';
@ -269,6 +285,7 @@ export default createComponent({
onBlur(event) {
this.focused = false;
this.$emit('blur', event);
this.validateWithTrigger('onBlur');
resetScroll();
},

View File

@ -411,6 +411,7 @@ export default {
| error-message-align | Error message align, can be set to `center` `right` | *string* | `left` |
| colon | Whether to display `:` after label | *boolean* | *false* |
| validate-first | Whether to stop the validation when a rule fails | *boolean* | `false` |
| validate-trigger `v2.5.2` | When to validate the formcan be set to `onChange``onSubmit` | *string* | `onBlur` |
### Events

View File

@ -443,6 +443,7 @@ export default {
| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | *string* | `left` |
| colon | 是否在 label 后面添加冒号 | *boolean* | *false* |
| validate-first | 是否在某一项校验不通过时停止校验 | *boolean* | `false` |
| validate-trigger `v2.5.2` | 表单校验触发时机,可选值为`onChange``onSubmit` | *string* | `onBlur` |
> 表单项的 API 参见:[Field 组件](#/zh-CN/field#api)

View File

@ -10,6 +10,10 @@ export default createComponent({
inputAlign: String,
validateFirst: Boolean,
errorMessageAlign: String,
validateTrigger: {
type: String,
default: 'onBlur',
},
},
provide() {

View File

@ -1,3 +1,4 @@
import { later } from '../../../test';
import { mountForm, submitForm, getSimpleRules } from './shared';
test('rules prop - execute order', async () => {
@ -167,3 +168,54 @@ test('error-message-align prop', () => {
});
expect(wrapper).toMatchSnapshot();
});
test('validate-trigger - onBlur', async () => {
const wrapper = mountForm({
template: `
<van-form ref="form">
<van-field name="A" :rules="rulesA" value="" />
</van-form>
`,
data: getSimpleRules,
});
const input = wrapper.find('input');
input.trigger('input');
await later();
expect(wrapper.contains('.van-field__error-message')).toBeFalsy();
input.trigger('blur');
await later();
expect(wrapper.contains('.van-field__error-message')).toBeTruthy();
});
test('validate-trigger - onChange', async () => {
const wrapper = mountForm({
template: `
<van-form validate-trigger="onChange" ref="form">
<van-field v-model="value" name="A" :rules="rulesA" />
</van-form>
`,
data() {
return {
...getSimpleRules(),
value: '',
};
},
});
const input = wrapper.find('input');
input.trigger('blur');
await later();
expect(wrapper.contains('.van-field__error-message')).toBeFalsy();
wrapper.setData({ value: '1' });
await later();
expect(wrapper.contains('.van-field__error-message')).toBeFalsy();
wrapper.setData({ value: '' });
await later();
expect(wrapper.contains('.van-field__error-message')).toBeTruthy();
});

View File

@ -7,15 +7,20 @@ export const FieldMixin = {
watch: {
value() {
if (this.vanField) {
this.vanField.resetValidation();
const field = this.vanField;
if (field) {
field.resetValidation();
field.validateWithTrigger('onChange');
}
},
},
created() {
if (this.vanField && !this.vanField.children) {
this.vanField.children = this;
const field = this.vanField;
if (field && !field.children) {
field.children = this;
}
},
};