Vue脚手架系列10-表单组件设计-Form组件检验方法完结
1.FormItem:
🤖思路:
Input组件中的内容,在FromItem的validate方法进行校验,校验的结果通过promise返回回去- 在
FormItem组件的生命周期中的mounted中,通过this.$parent.$emit('formItemAdd', this);调用FormComponent中的'formItemAdd'.
<template>
<div>
<!--如果有label显示,没有就隐藏 -->
<label v-if="label">{{label}}</label>
<!-- 插槽,用于放input组件的-->
<slot></slot>
<!-- 显示校验的错误信息-->
<p v-if="validateStatus==='error'" class="error">{{errorMessage}}</p>
</div>
</template>
<script>
//绑定label和prop属性
//获取当前输入框的规则
//如果输入框和ruler不匹配,显示错误信息
//input组件中,用户输入内容的时候,通知formItem的做校验(校验的方法)
//使用async-validate做校验
//npm i async-validator -S 安装
import Schema from 'async-validator';
export default {
data() {
return {
validateStatus: '', //校验的状态值
errorMessage: '', //显示的错误信息
};
},
inject: ['form'],
props: {
label: {
type: String,
default: '',
},
prop: {
//这个prop指的是age或者pass
type: String,
default: '',
},
},
//这里涉及一个生命周期的调用,子组件挂载完毕之后,再去走父组件的created方法
created() {
this.$on('validate', this.validate);
},
mounted() {
//这里必须做判断,因为FormComponent组件的子组件,不一定是FormItem
if (this.prop) {
this.$parent.$emit('formItemAdd', this);
}
},
methods: {
validate(value) {
//当前的value是输入框的值
console.log('我是输入框输入的值', value);
console.log('我是provide的form实例上的规则rules', this.form.rules);
console.log('我是prop', this.prop);
//🍊这里修改之前的部分,因为要使用Promise.all的方法去处理所有的tasks
return new Promise((resolve) => {
//下面开始进入校验的逻辑了
//此对象要存储校验规则这个校验规则(实际上是从Form组件中拿到的)
//让descriptor变成动态的值
// let descriptor = {};
// descriptor[this.prop] = this.form.rules[this.prop];
const descriptor = {
[this.prop]: this.form.rules[this.prop]
};
const validator = new Schema(descriptor);
// let obj = {};
// obj[this.prop] = value;
const obj = {
[this.prop]: value
};
validator.validate(obj, (errors) => {
if (errors) {
//显示你的错误
this.validateStatus = 'error';
this.errorMessage = errors[0].message;
resolve(false);
} else {
//没错误就将错误消息置空
this.validateStatus = '';
this.errorMessage = '';
resolve(true);
}
});
});
},
},
};
</script>
<style scoped>
.error {
color: red;
}
</style>
2.FormComponent组件:
🤖思路:
-
在
FormComponent组件中的created生命周期中,绑定formItemAdd,将每个FormItem校验项目(promise对象),push到filed数组中,filed中的每个子项都是一个promise对象。(当子组件FormItem加载完毕后,这里在created中进行一个接收,🤔就是由内而外的感觉,你懂的...) -
FormComponent组件中的validate方法,是在下面的Form组件中被调用的。 -
validate方法中通过Promise.all方法去验证每一个子项的,然后将结果的布尔值作为参数传给callback函数。
<template>
<div>
<!--插槽--用来包裹的FormItem等-->
<slot></slot>
</div>
</template>
<script>
export default {
//🌵通过provide将自己的实例传递给内层的FormItem,这样不管中间间隔了div或者其他元素,都可以获得rules
provide() {
return {
form: this,
};
},
//🌵当子组件FormItem加载完毕后,这里在created中进行一个接收
created() {
//🍊缓存需要校验的表单项目
this.fileds = [];
this.$on('formItemAdd', (item) => {
this.fileds.push(item);
});
},
props: {
model: {
type: Object,
required: true,
},
rules: {
type: Object,
},
},
methods: {
//🍊这里这里
validate(callback) {
//这里的tasks数组中,保存着多个输入验证之后的promise对象
const tasks = this.fileds.map((item) => item.validate());
let ret = true;
Promise.all(tasks).then((results) => {
//这里是每个task调用完事的结果组成的数组
console.log('我是PromiseAll的结果results', results);
//对结果数组results进行
results.forEach((valid) => {
if (!valid) {
ret = false;
}
});
//这个callback就是Form组件中调用时传递的
callback(ret);
});
},
},
};
</script>
<style scoped>
</style>
3.Form组件:
<template>
<div>
<!--这是我们自己的input组件-->
{{ruleForm}}
<m-form :model="ruleForm" :rules="rules" ref="rulebox">
<m-form-item label="用户名" prop="name">
<m-input v-model="ruleForm.name"></m-input>
</m-form-item>
<m-form-item label="年龄" prop="age">
<m-input type="age" v-model="ruleForm.age"></m-input>
</m-form-item>
<m-form-item lable="密码" prop="pass">
<m-input type="password" v-model="ruleForm.pass"></m-input>
</m-form-item>
<!--这里新加了按钮用于最后的提交-->
<m-form-item>
<el-button type="primary" @click="submitForm('rulebox')">提 交</el-button>
</m-form-item>
</m-form>
</div>
</template>
<script>
import MInput from './Input';
import MFormItem from './FormItem';
import MForm from './FormComponent';
export default {
components: {
MInput,
MFormItem,
MForm,
},
data() {
return {
ruleForm: {
pass: '98',
age: '18',
name: '索隆',
},
rules: {
name: [{
required: true,
message: '请输入名字',
},
{
min: 2,
max: 4,
message: '请输入2~4位用户名',
},
],
pass: [{
require: true,
message: '请输入密码',
},
{
min: 6,
max: 10,
message: '请输入6~10密码',
},
],
age: [{
require: true,
message: '请输入年龄',
}, ],
},
};
},
methods: {
submitForm(name) {
console.log(name);
console.log('我是validate的refs[name]', this.$refs);
//这里拿到的是FormComponent组件的实例去调用他的validate方法
this.$refs[name].validate((valid) => {
console.log('我是validate', valid);
if (valid) {
alert('哎呦不错哦,通过验证了');
} else {
alert('请仔细检查您的提交内容');
}
});
},
},
};
</script>