自己来实现封装一个element的表单

980 阅读1分钟

可能平时我们习惯用组件库去实现我们想要的功能,但是有时候需求太多获取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);      }    }

这样我们就能完整的实现表单验证的所有功能,如果以上有什么解释不是很清楚的,还希望小伙伴们提出建议哦。

觉得写得好不错的小伙伴们点个赞哦,谢谢各位了