表单组件实现
1.自定义Form组件
-
Form
给FormItem 留插槽
设置数据和校验规则
全局校验
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
provide() {
return {
form: this
}
},
props: {
model:{
type: Object,
required: true
},
rules: {
type: Object
}
},
methods: {
validate(cb){
const tasks = this.$children
.filter(item => item.prop)
.map(item => item.validate())
<!--所有的任务都ton过才算校验通过-->
Promise.all(tasks)
.then(() => cb(true))
.then(() => cb(false))
}
}
}
</script>
2.自定义FormItem组件
-
FormItem
给input预留插槽 slot
能够展示label和校验信息
能够进行校验
<template>
<div>
<label v-if="label">{{label}}</label>
<slot></slot>
<p v-if="errorMessage">{{errorMessage}}</p>
</div>
</tempalte>
<script>
//表单验证第三方库
import Schema from 'async-validator'
export default {
inject: ["form"],
props: {
label: {
type: String,
default: ""
},
prop: {
type: String
}
},
data() {
return {
errorMessage: ''
}
},
mounted() {
this.$on('validate',this.validate)
},
methods:{
validate() {
//做校验
const value = this.form.model[this.prop];
const rules = this.form.rules[this.prop]
const desc = {
[this.prop]:rules
}
const schema = new Schema(desc);
return schema.validate({[this.prop]: value}, errors => {
if(errors){
this.errorMessage = errors[0].message;
}else{
this.errorMessage = ''
}
})
}
}
}
</script>
3.自定义Input组件
input
- 双向绑定 @input :value
- 派发检验事件
<template>
<div>
<!--
1. :value="value" @input="onInput" 等于 v-model
2.$attrs 接受父组件的所有属性
-->
<input :value="value" @input="onInput" v-bind="$attrs">
</div>
</template>
export default {
inheritAttrs: false,
props:{
value:{
type:String,
default:""
}
},
methods: {
onInput(e) {
this.$emit('input', e.target.value)
//一旦触发输入框事件,就让父组件调用验证函数
this.$parent.$emit('validate')
}
}
}