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: { watch: {
value() { value() {
this.resetValidation(); this.resetValidation();
this.validateWithTrigger('onChange');
this.$nextTick(this.adjustSize); this.$nextTick(this.adjustSize);
}, },
}, },
@ -158,8 +159,8 @@ export default createComponent({
}); });
}, },
runRules() { runRules(rules) {
return this.rules.reduce( return rules.reduce(
(promise, rule) => (promise, rule) =>
promise.then(() => { promise.then(() => {
if (this.validateMessage) { if (this.validateMessage) {
@ -183,13 +184,13 @@ export default createComponent({
); );
}, },
validate() { validate(rules = this.rules) {
return new Promise(resolve => { return new Promise(resolve => {
if (!this.rules) { if (!rules) {
resolve(); resolve();
} }
this.runRules().then(() => { this.runRules(rules).then(() => {
if (this.validateMessage) { if (this.validateMessage) {
resolve({ resolve({
name: this.name, 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() { resetValidation() {
if (this.validateMessage) { if (this.validateMessage) {
this.validateMessage = ''; this.validateMessage = '';
@ -269,6 +285,7 @@ export default createComponent({
onBlur(event) { onBlur(event) {
this.focused = false; this.focused = false;
this.$emit('blur', event); this.$emit('blur', event);
this.validateWithTrigger('onBlur');
resetScroll(); resetScroll();
}, },

View File

@ -411,6 +411,7 @@ export default {
| 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` |
| colon | Whether to display `:` after label | *boolean* | *false* | | colon | Whether to display `:` after label | *boolean* | *false* |
| validate-first | Whether to stop the validation when a rule fails | *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 ### Events

View File

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

View File

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

View File

@ -1,3 +1,4 @@
import { later } from '../../../test';
import { mountForm, submitForm, getSimpleRules } from './shared'; import { mountForm, submitForm, getSimpleRules } from './shared';
test('rules prop - execute order', async () => { test('rules prop - execute order', async () => {
@ -167,3 +168,54 @@ test('error-message-align prop', () => {
}); });
expect(wrapper).toMatchSnapshot(); 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: { watch: {
value() { value() {
if (this.vanField) { const field = this.vanField;
this.vanField.resetValidation();
if (field) {
field.resetValidation();
field.validateWithTrigger('onChange');
} }
}, },
}, },
created() { created() {
if (this.vanField && !this.vanField.children) { const field = this.vanField;
this.vanField.children = this;
if (field && !field.children) {
field.children = this;
} }
}, },
}; };