kInput.vue
页面
- 数据的双向绑定
- 数据修改时通知
KFormItem.vue
组件做校验
<template>
<input :type="type" @input="onInput" :value="value" v-bind="$attrs"/>
</template>
<script>
export default {
name: 'KInput',
inheritAttrs: false,
props: {
value: {
type: String,
default: ''
},
type: {
type: String,
default: 'text'
},
},
data() {
return{
};
},
methods: {
onInput(e) {
this.$emit('input', e.target.value);
this.$parent.$emit('validate');
},
},
};
</script>
<style lang="scss" scoped>
</style>
KFormItem.vue
页面
- 对数据中的单个属性进行校验
- 显示错误信息
- 显示文本框标题(label)
<template>
<div>
<label v-if="label">{{label}}</label>
<slot></slot>
<p class="error" v-if="error">{{error}}</p>
</div>
</template>
<script>
import Schema from 'async-validator';
export default {
name: 'KFormItem',
inject: ['form'],
props: {
label: {
type: String,
default: '',
},
prop: {
type: String,
default: '',
},
},
data() {
return {
error: '',
};
},
mounted() {
this.$on('validate', () => {
if (this.prop) {
this.validate();
}
});
},
methods: {
validate() {
const rules = this.form.rules[this.prop];
const value = this.form.model[this.prop];
const descriptor = { [this.prop]: rules };
const schema = new Schema(descriptor);
return schema.validate({
[this.prop]: value,
}, errors => {
if (errors) {
this.error = errors[0].message;
} else {
this.error = '';
}
});
},
},
};
</script>
KForm.vue
页面
- 作为容器:包裹所有的表单控件
- 全局校验:汇总所包裹控件的校验结果,判断后返回最终验证结果
- 若所有控件校验结果皆为 true,则验证通过
- 只要有一个未通过,则验证不通过
- 定义提交方法
<template>
<form>
<slot></slot>
</form>
</template>
<script>
export default {
name: 'KForm',
provide() {
return {
form: this
};
},
props: {
model: {
type: Object,
required: true
},
rules: {
type: Object,
},
},
methods: {
validate(cb) {
const tasks = this.$children
.filter(item => !!item.prop && this.rules[item.prop])
.map(item => item.validate());
Promise.all(tasks)
.then(() => cb(true))
.catch(() => cb(false));
},
},
};
</script>