vue+element ui动态表单及多表单校验解决方案

1,109 阅读1分钟
  • 业务场景:直播路数每一路价格跟随支持最大同时直播数自动生成、年份折扣续费折扣可以自定义增减。
  • 解决方案: 表单数据只接收Object

dynamic.gif 在data里面初始化遍历生成表单的对象

data() {
    return {
         price_detail: {
        '1_line': {
          price: '',
          discount: '1'
        },
        '2_line': {
          price: '',
          discount: '1'
        },
        '3_line': {
          price: '',
          discount: '1'
        },
      },
      discountObj: {
        '1_year': {
          label: '1年折扣',
          value: '1'
        },
        '1_year_renew': {
          label: '1年续费折扣',
          value: '1'
        },
        '2_year': {
          label: '2年折扣',
          value: '1'
        },
        '2_year_renew': {
          label: '2年续费折扣',
          value: '1'
        },
        '3_year': {
          label: '3年折扣',
          value: ''
        },
        '3_year_renew': {
          label: '3年续费折扣',
          value: '1'
        }
      },
    }
}
    

这是template里模板写法:

          <el-form
            ref="price_detail"
            label-width="110px"
            :model="price_detail"
            :rules="rulesList"
            :hide-required-asterisk="false"
            inline
          >
            <div v-for="(item, key, i) in price_detail" :key="i">
              <el-form-item 
                :label="(++i) + '路价格(元/年)'" 
                :prop="key + '.price'"
                :rules="[
                  { required: true, message: '价格不能为空', trigger: 'blur' },
                ]"
                class="inputlang">
                <el-input v-model="price_detail[key].price" />
              </el-form-item>
              <el-form-item 
                :label="i + '路折扣'" 
                :prop="key + '.discount'"
                :rules="[
                  { required: true, message: '折扣不能为空', trigger: 'blur' },
                  { validator: judgeDiscount, trigger: 'blur'  }
                ]"
                class="inputlang">
                <el-input v-model="price_detail[key].discount" @input="((val) => { inputlineDiscount(val, key) })" />
              </el-form-item>
            </div>
          </el-form>
          <el-form
            ref="discountForm"
            label-width="110px"
            :model="discountObj"
            :rules="rulesList"
            :hide-required-asterisk="false"
            inline
          >
            <el-form-item 
              v-for="(item, key, i) in discountObj" 
              :key="i" 
              :label="item.label" 
              :prop="key + '.value'"
              :rules="[
                { required: true, message: '折扣不能为空', trigger: 'blur' },
                { validator: judgeDiscount, trigger: 'blur'  }
              ]"
              class="inputlang">
              <el-input v-model="discountObj[key].value" @input="((val)=>{inputDiscount(val, key)})" />
              <el-button v-if="yearFilter(key)" type="danger" icon="el-icon-delete" size="mini" circle @click="deleteItem(key)"></el-button>
            </el-form-item>
          </el-form>
          <el-button @click="addMoreDiscount" plain size="mini">新增折扣</el-button>

这里是methods里面的方法

// 点击新增折扣
    addMoreDiscount() {
      // console.log(currentMaxYear, '点击添加')
      currentMaxYear = Number(currentMaxYear) + 1
      if (currentMaxYear <= 10) {
        this.$set(this.discountObj, `${currentMaxYear}_year`, { label: `${currentMaxYear}年折扣`, value: '1' })
        this.$set(this.discountObj, `${currentMaxYear}_year_renew`, { label: `${currentMaxYear}年续费折扣`, value: '1' })
      } else {
        // console.log(currentMaxYear, '点击添加')
        this.$message.warning('暂不支持添加更多折扣!')
      }
    },
    // 点击提交
    submitForm() {
      // 避免重复点击的时候需检验的表单重复累加
      this.neededValidateForm.length = 0
      // 将需要校验的表单放进一个数组里面、,
      let forms = ['addnodeform', 'price_detail', 'discountForm']
      // 然后对数组进行遍历生成校验表单的promise函数
      forms.forEach(item => {
        this.checkForm(item)
      })
      //使用Promise.all(),对执行所有的promise
      Promise.all(this.neededValidateForm)
        .then(() => {
          this.loadingOfSave = true
          let buyDiscount = {}
          for (let item in this.discountObj) {
            buyDiscount[item] = this.discountObj[item].value
          }
          const data = {
            action: this.addnodeform.node_id ? 'update' : 'add',
            node_id: this.addnodeform.node_id ? this.addnodeform.node_id : undefined,
            line: this.addnodeform.line,
            status: this.addnodeform.status,
            node_names: {
              cn: this.addnodeform.node_name || undefined,
              cht: this.addnodeform.node_name_cht || undefined ,
              en: this.addnodeform.node_name_en || undefined,
            },
            buy_time_discount: buyDiscount,
            price_detail: this.price_detail,
            flag: this.addnodeform.node_id ? this.flagUrl : this.addnodeform.flag,
            line_coefficient: this.addnodeform.line_coefficient
          }
          actionLiveNode(data)
            .then((response) => {
              const { code } = response;
              if (code === 200) {
                this.loadingOfSave = false;
                this.$message({
                    type: 'success',
                    message: this.addnodeform.node_id ? '修改成功!' : '添加成功!'
                  })
                this.closeDialog()
                this.liveNodeList();
              }
            })
            .catch(() => {
              this.loadingOfSave = false;
            });
        })
             
    },
    checkForm(arrName) { 
    //根据form表单的ref,动态生成promise,再对其坐表单校验,都通过了再去做处理
      let _self = this
      let result = new Promise(function(resolve, reject) {
        // console.log(_self.$refs[arrName], '1111')
        _self.$refs[arrName].validate((valid) => {
            if (valid) {
                resolve();
            } else { reject() }
        })
      })
      this.neededValidateForm.push(result) //push 得到promise的结果
    },

以上就是整个的动态表单编写思路,在这里分享给有需要的伙伴,希望有所帮助。 还有留个问题,如果将动态表单的数据放到固定表单会怎么样?