多表单验证

1,821 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

需求

根据项目需求,现有四个 tab 标签,且每个 tab 标签中绑定了不同的 form 表单,要求在点击提交按钮时对这些表单进行验证,每个表单的值不能为空,所有验证通过以后才能进行下一步操作。

思路

  1. 生成表单名称数组集合(allForm),
  2. 页面上每个 el-form 标签添加与集合中表单名称一致的 ref 属性,
  3. 点击提交按钮,遍历 allForm 集合,将表单名称作为检验函数(checkForm)的参数并调用,
  4. 在检验函数中依次根据表单的 ref 进行校验,针对每一个表单如果有不通过项就返回校验失败信息并停止校验,如果该表单全部校验成功则返回校验成功信息并将成功信息 push 到一个数组(resultArr)中,然后才继续下一个表单的校验,校验方法同上,直到所有表单校验完毕为止,最后返回 resultArr 的 promise对象 ,
  5. 通过 Promise.all  获取校验成功信息并进行下一步操作。

代码实现

HTML代码

<template>
  <div class="app-container">
    <el-tabs v-model="activeName" type="card" style="height: 100%">
      <el-tab-pane label="第一页" name="form1">
        <el-form ref="form1" label-width="100px" :model="form1" :rules="rules">
          <el-form-item label="性别" prop="sex">
            <el-select v-model="form1.sex">
              <el-option label="男" value="1" />
              <el-option label="女" value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="身高" prop="height">
            <el-input v-model="form1.height" />
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="第二页" name="form2">
        <el-form ref="form2" label-width="100px" :model="form2" :rules="rules">
          <el-form-item label="年龄" prop="age">
            <el-input v-model="form2.age" />
          </el-form-item>
          <el-form-item label="姓名" prop="name">
            <el-input v-model="form2.name" />
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="第三页" name="form3">
        <el-form ref="form3" label-width="100px" :model="form3" :rules="rules">
          <el-form-item label="体重" prop="weight">
            <el-input v-model="form3.weight" />
          </el-form-item>
          <el-form-item label="邮箱" prop="email">
            <el-input v-model="form3.email" />
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="第四页" name="form4">
        <el-form ref="form4" label-width="100px" :model="form4" :rules="rules">
          <el-form-item label="地址" prop="address">
            <el-input v-model="form4.address" />
          </el-form-item>
          <el-form-item label="联系电话" prop="phone">
            <el-input v-model="form4.phone" />
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>

    <el-button type="primary" @click="submit()">提交</el-button>
  </div>
</template>

Script 代码

<script>
export default {
  data() {
    return {
      activeName: "form1", //当前表单
      allForm: ["form1", "form2", "form3", "form4"], //表单集合
      resultArr: [], //验证结果集

      // 表单
      form1: {
        sex: "",
        height: "",
      },
      form2: {
        age: "",
        name: "",
      },
      form3: {
        weight: "",
        email: "",
      },
      form4: {
        address: "",
        phone: "",
      },

      // 校验规则
      rules: {
        sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
        height: [{ required: true, message: "身高不能为空", trigger: "blur" }],
        age: [{ required: true, message: "年龄不能为空", trigger: "blur" }],
        name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
        weight: [{ required: true, message: "体重不能为空", trigger: "blur" }],
        email: [{ required: true, message: "邮箱不能为空", trigger: "blur" }],
        address: [{ required: true, message: "地址不能为空", trigger: "blur" }],
        phone: [
          { required: true, message: "联系方式不能为空", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    submit() {
      // 多表单校验
      this.allForm.forEach((item) => {
        // 根据表单的ref校验
        this.checkForm(item); // 封装的校验函数
      });

      // 校验通过后调接口
      // resultArr数组的值必须是promise对象才能使⽤Promise.all,在checkForm做了这⼀步
      var promiseArr = [];
      for (var index in this.resultArr) {
        promiseArr.push(this.resultArr[index]["value"]);
      }
      Promise.all(promiseArr).then((res) => {
        console.log(res);
        // 验证通过后做点什么
      });
    },

    // 表单校验函数
    checkForm(formName) {
      const result = new Promise((resolve, reject) => {
        // 这里必须用箭头函数,否则this.$refs报错
        // 或者使用const that = this,that.$refs
        this.$refs[formName].validate((valid) => {
          if (valid) {
            resolve(formName + ":表单验证通过!");
          } else {
            reject(formName + ":表单验证不通过!");
          }
        });
      });

      // 避免重复塞入成功信息
      if (JSON.stringify(this.resultArr).indexOf(formName) > -1) {
        for (var index in this.resultArr) {
          if (this.resultArr[index]["name"] === formName) {
            this.resultArr[index]["value"] = result;
          }
        }
      } else {
        this.resultArr.push({
          name: formName,
          value: result,
        });
      }
    },
  },
};
</script>

效果展示

1.gif