ElementUi表单组件的实现

387 阅读1分钟

表单组件实现

1.自定义Form组件

  • Form

    给FormItem 留插槽

    设置数据和校验规则

    全局校验

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

<script>
  export default {
      provide() {
          return {
              form: this
          }
      },
      props: {
          model:{
              type: Object,
              required: true
          },
          rules: {
            type: Object
          }
      },
      methods: {
          validate(cb){
              const tasks = this.$children
               .filter(item => item.prop)
               .map(item => item.validate())
               
               <!--所有的任务都ton过才算校验通过-->
               
               Promise.all(tasks)
                .then(() => cb(true))
                .then(() => cb(false))
          }
      }
  }

</script>

2.自定义FormItem组件

  • FormItem

    给input预留插槽 slot

    能够展示label和校验信息

    能够进行校验

  <template>
    <div>
        <label v-if="label">{{label}}</label>
        <slot></slot>
        <p v-if="errorMessage">{{errorMessage}}</p>
    </div>
  </tempalte>
  
  <script>
     //表单验证第三方库
    import Schema from 'async-validator'
    export default {
        inject: ["form"],
        props: {
            label: {
                type: String,
                default: ""
            },
            prop: {
                type: String
            }
        },
        data() {
            return {
                errorMessage: ''
            }
        },
        mounted() {
            this.$on('validate',this.validate)
        },
        methods:{
            validate() {
                //做校验
                const value = this.form.model[this.prop];
                const rules = this.form.rules[this.prop]
                const desc = {
                    [this.prop]:rules
                }
                const schema = new Schema(desc);
                
                return schema.validate({[this.prop]: value}, errors => {
                 if(errors){
                     this.errorMessage = errors[0].message;
                 }else{
                     this.errorMessage = ''
                 }
                })
            }
        }
    }
  </script>

3.自定义Input组件

input

  • 双向绑定 @input :value
  • 派发检验事件
 <template>
    <div>
    <!--
    1. :value="value" @input="onInput" 等于 v-model
    2.$attrs 接受父组件的所有属性
    -->
        <input :value="value" @input="onInput" v-bind="$attrs">
    </div>
 </template>
 
 export default {
     inheritAttrs: false,
     props:{
        value:{
          type:String,
          default:""
        }
     },
     methods: {
         onInput(e) {
             this.$emit('input', e.target.value)
             //一旦触发输入框事件,就让父组件调用验证函数
             this.$parent.$emit('validate')
             
         }
     }
 }