可能平时我们习惯用组件库去实现我们想要的功能,但是有时候需求太多获取ui的需求界面差别太大,我们直接去改组件库,要改的可能太多了,那我们为何不自己去封装一个组件库呢?,既能够提升自己封装的能力,后期维护也比较方便,所以我仿制element,实现一个自己的组件库,废话不多说啦。直接上代码。
我们平时使用element表单的时候,我们知道是由三个子组件组成,所以我们首先创建3个子组件分别是lForm,lFormItem,lInput,可能一开始我们没有思路怎么去实现element组件的功能,按我们就先从input组件开始:
<template lang="">
<div>
<input :value="value" :type="type" @input="onInput"/>
</div>
</template>
<script>
export default
{
name: 'lInput',
props:{
value:{ type: String, default: '' },
type:{ type: String, default: '' },
},
methods:{
onInput(e) {
this.$emit('input', e.target.value)
}
}}
</script>
<style> </style>
上面可能就只是简单打双向数据绑定,在formTest里面绑定你的属性
接下来就是重点来了,我们需要实现的怎么改变输入框的值的时候,实现表单验证,我们知道规则,和数据是绑定在form组件上面的,可是我们表单验证是在formItem实现的,所以我们需要用到一个属性provite
provide(){
return{
form: this //表示from表单组件的实例
}
},
那么我们就可以在formItem组件当中使用infect: ['form']获取组件的实例,那么我们就可以formItem里面进行表单验证了,代码如下
<template lang=""> <div class="fromItem"> <p v-if="label">{{label}}</p> <!-- 插槽 --> <slot></slot> <!-- 检验错误信息 --> <p v-if="errorMessage" style="color:red">{{errorMessage}}</p> </div></template><script>import Validator from "async-validator";import { Promise } from "q";export default { name: 'lInput', inject: ['form'], props: ["label", "prop"], data() { return { errorMessage: "" }; }, created() { this.$on('validate', this.validate) //获取子组件传过来的值 }, methods:{ validate() { return new Promise(resolve => { // 校验规则制定 const descriptor = { [this.prop]: this.form.rules[this.prop] }; // 创建校验器 const validator = new Validator(descriptor); // 执行校验 validator.validate( { [this.prop]: this.form.model[this.prop] }, errors => { if (errors) { // 显示错误信息 this.errorMessage = errors[0].message; resolve(false); } else { this.errorMessage = ""; resolve(true); } } ); }); } }}</script><style scoped>p{ margin-bottom: 40px}</style>
最后还有一点,为什么我们要把validate封装成promise呢,是因为我们点击提交的时候,我们需要重新去验证所有的表单,我们要所有的结果,然后去做我们想要的操作
async validate(cb) { //执行表单中的所有表单校验 const tasks = this.$children .filter(item => item.prop) .map(item => item.validate()) // tasks中任意false就校验失败 const results = await Promise.all(tasks); if (results.some(valid => !valid)) { // 校验失败 cb(false); } else { cb(true); } }
这样我们就能完整的实现表单验证的所有功能,如果以上有什么解释不是很清楚的,还希望小伙伴们提出建议哦。
觉得写得好不错的小伙伴们点个赞哦,谢谢各位了