element-ui表单的多层循环验证处理

4,465 阅读1分钟

当时在使用element-ui开发后台项目的时候,遇到表单中数组字段需要验证,试了好几种写法都没能弄出来,甚至当时都没想到该怎么描述去百度搜索别人的经验借鉴一下,现在我将这个现象记录下来,方便自己,也希望能帮助还没遇到或者即将遇到此问题的你。

当时的需求:

选择允许加床数量,会自动创建选中数量的加床模板,加床模板字段包含加床类型、是否免费。加床模板就是一个数组,每个模板中的字段(加床类型、是否免费)同时也需要验证。

先贴个效果截图 1621224041(1).png

下面贴上部分源码,后面再解释一下:

form4.vue中需要验证的部分代码

<el-form 
  :model="form" 
  label-position="top"
  v-show="stepIndex==0"
 >
    <template v-if="form.allowExtraBed == 1">
      <div v-for="(item, index) in form.extraBedData" :key="index">
        <div class="area-wrapper">
          <h3>加床{{ index + 1 }}</h3>

          <el-form-item
            label="加床类型"
            :prop="`extraBedData.${index}.extraBedType`"
            verify
          >
            <el-select
              v-model="item.extraBedType"
              placeholder="请选择"
              style="width: 100%"
              clearable
            >
              <el-option
                v-for="item in dict.extra_bed_type"
                :key="item.dataValue"
                :label="item.dataName"
                :value="item.dataValue"
              >
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item
            label="是否免费"
            :prop="`extraBedData.${index}.free`"
            verify
          >
            <el-select
              v-model="item.free"
              placeholder="请选择"
              style="width: 100%"
              clearable
            >
              <el-option
                v-for="item in [
                  { dataName: '是', dataValue: 1 },
                  { dataName: '否', dataValue: 0 },
                ]"
                :key="item.dataValue"
                :label="item.dataName"
                :value="item.dataValue"
              >
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item
            v-if="item.free == 0"
            label="加床价格"
            :prop="`extraBedData.${index}.extraBedFee`"
            :verify="{ type: 'pint', lte: 999 }"
          >
            <el-input placeholder="请输入内容" v-model="item.extraBedFee">
              <template slot="append">/元</template>
            </el-input>
          </el-form-item>
        </div>
      </div>
    </template>
</el-form>  

大家注意,其实多层循环验证核心就是在el-form-item 上 的 :prop="extraBedData.${index}.extraBedType"

extraBedData就是数组名,index是数组循环索引值,extraBedType为需要验证的字段。

总结起来就是: :prop="数组字段.${数组循环索引值}.数组对象中需要验证的字段"

遇到问题不要慌,多想想,查查资料,或者请教下同事朋友,困难并不可怕。

哦,对了,大家是否看到了我代码中的verify,这是我们公司里曾经的一会小伙伴基于element-ui开发的一款表单验证的插件,名为element-form-verify,方便验证而已,有兴趣的可以拿来使用,当然你直接使用element-ui提供的rules来验证也是没有任何问题的,譬如上面的

<el-form-item
    label="是否免费"
    :prop="`extraBedData.${index}.free`"
    verify
>
</el-form-item>

就可以这样写

 <el-form-item
    label="是否免费"
    :prop="`extraBedData.${index}.free`"
    :rules="{
        required: true,
        message: '必填项',
    }"
>
</el-form-item>

好了,关于多层循环验证的问题就啰嗦到这里啦。

下面记录下这个页面的js,当然,跟我们讨论的问题无关啦,大家可以略过。

import { mapGetters } from "vuex";
export default {
  props: {
    form: {
      type: Object,
      required: true,
      default() {
        return {};
      },
    },
    status: {
      type: String,
      required: true,
    },
  },
  computed: {
    ...mapGetters(["dict"]),
  },
  data() {
    return {};
  },
  watch: {
    // 是否允许加床选择否,清空加床信息、加床数量
    "form.allowExtraBed": {
      handler(nv, ov) {
        if (nv == 0) {
          this.$set(this.form, "extraBedData", []);
          this.$set(this.form, "extraBedNum", null);
        }
        if (nv == 1) {
          if (
            !this.form.extraBedData ||
            (this.form.extraBedData.constructor === Array &&
              this.form.extraBedData.length == 0)
          ) {
            this.$set(this.form, "extraBedNum", 1);
            this.onExtraBedNumChange(1);
          }
        }
      },
      immediate: true,
      deep: true,
    },
  },
  methods: {
    onExtraBedNumChange(nv) {
      let temp = [];
      for (let i = 0; i < nv; i++) {
        temp.push({
          extraBedType: null,
          free: null,
          extraBedFee: null,
        });
      }
      this.$set(this.form, "extraBedData", temp);
    },
  },
};