Vue+ElementUI How to Handle Large Form Example Explanation

  • 2021-12-09 08:12:56
  • OfStack

Recently, due to the business adjustment of the company, the logic of the previous super-long form has changed a lot, so I plan to reconstruct it (it was written by a retired background without comments, and a component wrote 4000 + lines, which is really powerless). For your convenience, I have split 14 components in the project and streamlined them.

Overall thinking

Large forms are split according to business modules Use validate method provided by el-form to verify when saving (check every 1 split component cyclically) Common extraction of each component by mixin (also for later project maintenance)

Begin

Here, take splitting two components as an example: form1 and form2 (convenient for readers to watch, named do not spray)

Here, why ref and model are bound to form will be explained later (for convenience of later maintenance)


// form1  Component 
<template>
    <el-form
      ref="form"
      :model="form"
      label-width="10px"
    >
      <el-form-item label=" Name " prop="name">
          <el-input v-model="form.name" />
      </el-form-item>
    </el-form>
</template>
<script>
export default {
  name: 'Form1',
    props: {
      form: {}
  },
  data() {
    return {
      rules: {
        name: [
          { required: true, message: ' Please enter a name ', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    //  This is for the parent component to call the validation loop 
    validForm() {
        let result = false
        this.$refs.form.validate(valid => valid && (result = true))
        return result
    }
    //  I also used another 1 It is written in a way, but when it is cyclic checking, it is promise Object, there is a problem, hope that the big brothers will give advice 12
    validForm() {
        //  Clearly, the output structure here is  Boolean  Value, but after the parent component loops, it is promise Type, which needs to be converted 1 Just go down 
        return this.$refs.form.validate().catch(e => console.log(e))
    }
  }
}
</script>
 
// form2  Component 
<template>
    <el-form
      ref="form"
      :model="form"
      label-width="10px"
    >
      <el-form-item label=" Age " prop="age">
          <el-input v-model="form.age" />
      </el-form-item>
    </el-form>
</template>
<script>
export default {
  name: 'Form2',
  props: {
      form: {}
  },
  data() {
    return {
      rules: {
        name: [
          { required: true, message: ' Please enter an age ', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    //  This is for the parent component to call the validation loop 
    validForm() {
        let result = false
        this.$refs.form.validate(valid => valid && (result = true))
        return result
    }
  }
}
</script>

See how the parent component is referenced under 1


//  Parent component 
<template>
    <div class="parent">
        <form1 ref="form1" :form="formData.form1" />
        <form2 ref="form2" :form="formData.form2" />
        <el-button type="primary" @click="save"> Report an error </el-button>
    </div>
</template>
<script>
...  Omit a reference 
export default {
    name: 'parent',
    ...  Omit registration 
    data () {
        return {
            formData: {
                form1: {},
                form2: {}
            }
        }
    },
}
</script>

Because the attribute names form1 and form2 in formData are used on ref of the subform component, they can be found in turn during the traversal, and the save function can be modified. The code is as follows:


methods: {
    save () {
        //  Object for each form object  key  Value, that is, the value of each form  ref  Value 
        const formKeys = Object.keys(this.formData)
        //  Execute the validation method for each form 
        const valids = formKeys.map(item => this.$refs[item].validForm())
        //  Logic after all forms pass verification 
        if (valids.every(item => item)) {
          console.log(11)
        }
    }
}

Answer why both components ref and model are bound to form

By comparison, we can find that form1 form2 has a common props methods We extracted 1 through mixin

export default {
  props: {
    form: {
      required: true,
      type: Object,
      default: () => {}
    },
  },
  methods: {
    validForm () {
      let result = false
      this.$refs.form.validate(valid => valid && (result = true))
      return result
    }
  }
}

Refer to the minix in form1 form2 and delete the corresponding attributes and methods in the corresponding components

End

Oversized forms are very troublesome to solve, and this is just a split of components The linkage between components is also a major difficulty, and it will be sent out after the next arrangement

Related articles: