手动实现一个form组件

最近研究了一下element-ui,想着手动实现一下里面的form组件,贴个组件里面的代码

<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
  <el-form-item label="密码" prop="pass">
    <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="确认密码" prop="checkPass">
    <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="年龄" prop="age">
    <el-input v-model.number="ruleForm.age"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
    <el-button @click="resetForm('ruleForm')">重置</el-button>
  </el-form-item>
</el-form>

 该组件可以细分为三个组件form,formItem以及input组件,首先介绍input组件

  1. input组件:任务一是实现一个v-model的数据双绑定,即包含value的动态绑定以及input的实现   

           任务二是值发生改变的时候通知formItem组件 

    

<template>
  <div>
    <input type="text" :value="value" @input="input">
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: String,
      default: ""
    }
  },
  methods: {
    input(e) {
      let inputValue = e.target.value;
      this.$emit("input", inputValue);
      this.$parent.$emit('validate');
    }
  }
};
</script>

<style lang="scss" scoped>
</style>

 

    2. FormItem组件: 任务一实现一个插槽

            任务二显示label以及校验信息

            任务三  对数据进行校验

<template>
  <div>
    <label :prop="prop">{{label}}</label>
    <slot></slot>
    <p>{{error}}</p>
  </div>
</template>

<script>
//需要知道何时去校验
import Schema from "async-validator";
export default {
  inject: ["form"],
  props: {
    prop: {
      type: String,
      default: ""
    },
    label: {
      type: String,
      default: ""
    }
  },
  data() {
      return {
          error: ''
      }
  },
  methods: {
    validate() {
      const rules = this.form.rules[this.prop]; //数组
      const value = this.form.model[this.prop];
      const descriptor = { [this.prop]: rules };
      const schema = new Schema(descriptor);
      schema.validate({ [this.prop]: value }, errors => {
        if (errors) {
          this.error = errors[0].message;
        } else {
          this.error = "";
        }
      });
    }
  },
  mounted() {
    this.$on("validate", this.validate);
  }
};
</script>

<style lang="scss" scoped>
</style>

 

    3.  Form组件: 任务实现rules和model的传递,预留插槽

<template>
  <div>
    <form>
      <slot></slot>
    </form>
  </div>
</template>

<script>
export default {
  provide() {
    return {
      form: this
    };
  },
  props: {
    rules: {
      type: Object
    },
    model: {
      type: Object
    }
  }
};
</script>

<style lang="scss" scoped>
</style>

完整代码可以访问https://github.com/LinNigo/FormComponent

posted @ 2019-08-07 17:08  yinping  阅读(395)  评论(0编辑  收藏  举报