vue 组件设计:实现Form, Formltem, Input
需要思考的几个问题?
- Input是自定义组件,它是怎么实现双向绑定的?
- Formltem是怎么知道执行校验的,它是怎么知道Input状态的?它是怎么获得对应数据模型的?
- Form是怎么进行全局校验的?它用什么办法把数据模型和校验规则传递给内部组件?
实现 input
- 实现自定义组件双向绑定功能
v-model 是语法糖,实现自定义组件需要指定:value
@input
即可 - 值发生变化能通知
FormItem
组件
<input :type="type" :value="value" @input="onInput">
export default {
props:{
value:{
type:String,
default:''
},
type:{
type:String,
default:'text'
}
},
methods: {
onInput(e) {
let value = e.target.value;
//input 事件触发设置模型的值并通知父组件
this.$emit('input',value);
this.$parent.$emit('validate')
}
},
}
实现 FormItem
- 给
input
预留插槽solt
- 能展示label 和校验信息
- 能够进行校验
<div>
<label for="">{{label}}</label>
<div>
<slot></slot> // 插槽
<p v-if="errStatus">{{errMessage}}</p>
</div>
</div>
export default {
inject:['kForm'],
props:['label','prop'],
data() {
return {
errMessage: '',
errStatus: false
}
},
mounted(){
this.$on('validate',this.validator)
},
methods: {
validator() {
//有两个input! 一个用户名 一个密码
const rules = this.kForm.rules[this.prop];
const value = this.kForm.model[this.prop];
// 描述对象
const descriptor = {[this.prop]:rules};
const schema = new Schema(descriptor);
schema.validate({[this.prop]:value},errors =>{
if(errors){
this.errMessage = errors[0].message;
this.errStatus = true;
} else {
this.errMessage = '';
this.errStatus = '';
}
})
}
},
}
实现 Form
- 给
Form-item
预留槽位 - 将数据传递给后代便于它们访问数据模型和校验规则
vue provide provide
&&inject
<form>
<slot></slot>
</form>
export default {
provide(){
return {
form: this //组件实例作为提供者,子代组件可方便获取
}
},
props:{
model:{
type:Object,
required:true
},
rules:{
type:Object
}
}
}
数据校验
- 思路:校验发生在
FormItem
,他需要知道何时校验(让input
去通知),还需要怎么去校验他(注入校验规则) input
通知校验- input 中的 oninput方法
onInput(e) {
let value = e.target.value;
//input 事件触发设置模型的值并通知父组件
this.$emit('input',value);
//$parent指向 `FormItem`
this.$parent.$emit('validate')
}
- FormItem监听校验通知,获取规则并执行校验
import Schema from 'async-validator'
inject:['kForm'],//注入
mounted(){
//监听校验事件
this.$on('validate',this.validator)
},
methods: {
validator() {
//有两个input! 一个用户名 一个密码
//获取对应 的FormItem校验规则
const rules = this.kForm.rules[this.prop];
//获取校验值
const value = this.kForm.model[this.prop];
// 描述对象
const descriptor = {[this.prop]:rules};
//创建校验器
const schema = new Schema(descriptor);
schema.validate({[this.prop]:value},errors =>{
if(errors){
//将错误学习显示
this.errMessage = errors[0].message;
this.errStatus = true;
} else {
//校验通过
this.errMessage = '';
this.errStatus = '';
}
})
}