Input Components
Features:
- Data double bind
- Notice FormItem component check
<template>
<div>
<input :type="type" :value="value" @input="onInput" v-bind="$attrs" >
</div>
</template>
<script>
export default {
inheritAttrs:false,
props:{
value:{
type: String,
default: ''
},
type:{
type: String,
default: 'text'
},
},
methods:{
onInput(e){
this.$emit('input',e.target.value);
// 让父组件自己派发自己监听该valid事件进行校验。
this.$parent.$emit('valid');
}
}
}
</script>
$attrs
And v-bind="$attrs"
use
$attrs
Vue built-in properties is used to store the external transfer but was not received props to a component property.- These attributes have non-prop characteristics :
1 will be automatically added to the root element assembly.
2. By default, the characteristic properties of non-prop will overwrite the contents of the same name of the root element assembly. Forstyle
andclass
have special handling: merge (but if it is the style of the same name will be overwritten)
3. If you do not want to inherit the root element of non prop assembly features, you can configure the component configuration itemsinheritAttrs:false
(API has no effect on the style and class)
v-bind="$attrs"
It is $attrs
a method of deconstruction assignment, deconstruct :key="value"
form.
FormItem components
Features:
- check
- label display
- Error display
<template>
<div>
<label v-if="label">{{label}}</label>
<slot></slot>
<p v-if="error">{{error}}</p>
</div>
</template>
<script>
import Schema from 'async-validator'; // 校验包
export default {
inject:['form'],
props:{
label:{
type:String,
default:''
},
prop:{
type:String,
default:''
}
},
data(){
return {
error:''
}
},
mounted(){
this.$on('valid',()=>{
this.validate();
})
},
methods:{
validate(){
const rules = this.form.rules[this.prop];
const value = this.form.model[this.prop];
const schema = new Schema({[this.prop]:rules});
// 返回Promise<Boolean>
return schema.validate({[this.prop]:value},(errors)=>{
if(errors){
this.error = errors[0].message;
}else{
this.error = '';
}
})
}
}
}
</script>
Form Components
Features:
- Provide value
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
provide(){
return {
form:this // 把form组件实例传给后代,后代可以通过该实例访问该组件上的属性 model、rule ...
}
},
props:{
model:{
type:Object,
reuqired:true
},
rules:{
type:Object,
}
},
methods:{
validate(cb){
const checkRes = this.$children
.filter(item => item.prop)
.map(item => item.validate());
Promise.all(checkRes)
.then(()=>cb(true))
.catch(()=>cb(false));
}
}
}
</script>
Universal library development and inter-level commonly used method of mass participation provide / inject
- Ancestor has set
provide
configuration items, similar to thedata
usage, but its data is used to future generations, not for my own use. Offspring by
inject
acquiring data progenitor provide configuration items.inject: ['form'] // 祖代provide中的key值
The introduction of third-party libraries can be avoided by the way, such as vuex, if not deep level need to
props
approach cumbersome transfer.
use
<template>
<div>
<Form :model="model" :rules="rules" ref="myform">
<FormItem label="用户名" prop="username">
<Input v-model="model.username" placeholder="输入用户名" @ev="func" />
</FormItem>
<FormItem label="密码" prop="password" >
<Input v-model="model.password" placeholder="输入密码" type="password" @ev="func" />
</FormItem>
<FormItem >
<button @click="submitForm('myform')">提交</button>
</FormItem>
</Form>
</div>
</template>
<script>
import Input from '@/components/form/Input';
import Form from '@/components/form/Form';
import FormItem from '@/components/form/FormItem';
export default {
components:{
Input,
Form,
FormItem
},
data(){
return{
model:{
username:'',
password:'',
},
rules:{
username:[{required:true,message:'用户名必填'}],
password:[{required:true,message:'密码必填'}],
},
}
},
methods:{
submitForm(form){
this.$refs[form].validate(valid=>{
if(valid){
alert('校验通过');
}else{
alert('校验失败');
}
})
}
}
}
</script>
conclusion of issue
- Why is the data model model on the form?
In order to facilitate verification, validation within FormItem From there may be many, if they are written in FormItem will be very cumbersome. - Why write on FormItem prop?
In order to determine which part of the model is carried out in the check, but also to get rules through this key prop.