【vue+elementUI】自定义表单验证

971 阅读2分钟

Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。校验规则参见 async-validator

直接拿elementUI的全部代码举例:

一、HTML代码块:

    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="活动名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="活动区域" prop="region">
        <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="活动时间" required>
        <el-col :span="11">
          <el-form-item prop="date1">
            <el-date-picker
              type="date"
              placeholder="选择日期"
              v-model="ruleForm.date1"
              style="width: 100%;"
            ></el-date-picker>
          </el-form-item>
        </el-col>
        <el-col class="line" :span="2">-</el-col>
        <el-col :span="11">
          <el-form-item prop="date2">
            <el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
          </el-form-item>
        </el-col>
      </el-form-item>
      <el-form-item label="即时配送" prop="delivery">
        <el-switch v-model="ruleForm.delivery"></el-switch>
      </el-form-item>
      <el-form-item label="活动性质" prop="type">
        <el-checkbox-group v-model="ruleForm.type">
          <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
          <el-checkbox label="地推活动" name="type"></el-checkbox>
          <el-checkbox label="线下主题活动" name="type"></el-checkbox>
          <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="特殊资源" prop="resource">
        <el-radio-group v-model="ruleForm.resource">
          <el-radio label="线上品牌商赞助"></el-radio>
          <el-radio label="线下场地免费"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="活动形式" prop="desc">
        <el-input type="textarea" v-model="ruleForm.desc"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>

二、js代码块:

<script>
export default {
  data() {
    return {
      ruleForm: {
        name: "",
        region: "",
        date1: "",
        date2: "",
        delivery: false,
        type: [],
        resource: "",
        desc: "",
      },
      rules: {
        name: [
          { required: true, message: "请输入活动名称", trigger: "blur" },
          { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
        ],
        region: [
          { required: true, message: "请选择活动区域", trigger: "change" },
        ],
        date1: [
          {
            type: "date",
            required: true,
            message: "请选择日期",
            trigger: "change",
          },
        ],
        date2: [
          {
            type: "date",
            required: true,
            message: "请选择时间",
            trigger: "change",
          },
        ],
        type: [
          {
            type: "array",
            required: true,
            message: "请至少选择一个活动性质",
            trigger: "change",
          },
        ],
        resource: [
          { required: true, message: "请选择活动资源", trigger: "change" },
        ],
        desc: [{ required: true, message: "请填写活动形式", trigger: "blur" }],
      },
    };
  },
  methods: {
    submitForm() {
      this.$refs[ruleForm].validate((valid) => {
        if (valid) {
          alert("submit!");
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm() {
      this.$refs[ruleForm].resetFields();
    },
  },
};
</script>

三、使用elementUI提供的校验规则:

1.定义验证规则。

首先需要在data中定义验证规则rules对象,rules对象的第一层属性是表单绑定的数据对象。eg:

//取上面部分验证规则作展示
   data() {
      return {
        ruleForm: {  //表单绑定的数据(对象形式存储)
          name: '',
          region: '',
          date1: '',
          date2: '',
          delivery: false,
          type: [],
          resource: '',
          desc: ''
        },
        rules: { 
          name: [  //定义对ruleForm.name的验证规则
            { required: true, message: '请输入活动名称', trigger: 'blur' },
            { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
          ],
          region: [  //定义对ruleForm.region的验证规则
            { required: true, message: '请选择活动区域', trigger: 'change' }
          ]
          //required:指定必须校验字段;
          //type:内容必须为指定类型;
          //message:提示信息;
          //trigger:触发验证的事件,有blur和change;
          //max:指定内容的最大长度;
          //min:指定内容的最小长度;
        }
      };
    },
  },

2.el-form绑定验证规则。

<el-form
    :model="ruleForm"  //表单双向绑定的数据
    :rules="rules"  //表单绑定的验证规则
    ref="ruleForm"
    label-width="100px"
    class="demo-ruleForm"
 >

3.el-form-item配置prop属性,表明验证表单绑定的数据中的哪个字段。

      //此处prop属性值为name,即校验ruleForm中的name
      <el-form-item label="活动名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      
      //此处prop属性值为region,即校验ruleForm中的region
      <el-form-item label="活动区域" prop="region">
        <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>

4.在业务逻辑中使用,eg:提交表单的函数中。

methods: {
    submitForm() {  //验证表单会返回一个value,值为Boolean类型
      //$refs通过el-form的ref属性获取节点对象
      //使用elementUI提供的validate方法,其中需要传回调
      this.$refs[ruleForm].validate((valid) => {
        //如果全部字段通过验证,返回true
        if (valid) {
          ......
        } 
        else {  //如果有字段未能通过验证,则返回false
          ......
          return false;
        }
      });
    }
}

注意:如果验证的回调需要进行异步操作,要注意async/await的位置。

methods: {
    submitForm() {  //注意async的书写位置                   
      this.$refs[ruleForm].validate( async (valid) => {
        if (valid) {
          ......
          let res = await getUserAPI()
        } 
        else { 
          ......
          return false;
        }
      });
    }
}

四、自定义校验规则:

1.在表单双向绑定数据对象与使用prop声明验证的字段与上面一样。

2.自定义校验规则。

 //以下代码实例校验的对象和上面的代码不是同一个!!
 data() {
    //定义对ruleForm.age字段的校验规则
    var checkAge = (rule, value, callback) => {
      if (!value) {
        return callback(new Error("年龄不能为空"));
      }
      setTimeout(() => {
        if (!Number.isInteger(value)) {
          callback(new Error("请输入数字值"));
        } else {
          if (value < 18) {
            callback(new Error("必须年满18岁"));
          } else {
            callback();  //自定义校验 callback 必须被调用
          }
        }
      }, 1000);
    };
    
    //定义对ruleForm.pass字段的校验规则
    var validatePass = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入密码"));
      } else {
        if (this.ruleForm.checkPass !== "") {
          this.$refs.ruleForm.validateField("checkPass");
        }
        callback();  //自定义校验 callback 必须被调用
      }
    };
    
    //定义对ruleForm.checkPass字段的校验规则
    var validatePass2 = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("密码不能为空"));
      } else if (value !== this.ruleForm.pass) {
        callback(new Error("两次输入密码不一致!"));
      } else {
        callback();  //自定义校验 callback 必须被调用
      }
    };
    
    // rule:自定义的校验规则
    // value:待校验的用户输入的内容
    // callback:放行函数,或许和路由守卫中的next()差不多
    
    return {
    //表单双向绑定的数据-ruleForm对象
      ruleForm: {
        pass: "",
        checkPass: "",
        age: "",
      },
      
      //在data定义的存放校验规则的对象-rules对象
      rules: {
        pass: [{ validator: validatePass, trigger: "blur" }],
        checkPass: [{ validator: validatePass2, trigger: "blur" }],
        age: [{ validator: checkAge, trigger: "blur" }],
      },
    }; 
  }
methods: { 
  submitForm() { 
      this.$refs[ruleForm].validate((valid) => { 
        if (valid) { 
          alert('submit!'); 
        } else { 
          console.log('error submit!!'); 
          return false; 
        } 
      }); 
  }
}  
 

触发流程大概是(不太确定):

点击事件提交表单,validate()事件触发,触发后找到校验规则合集rules对象(它指定了需要校验的字段、校验该字段的规则以及触发校验的事件),触发rules包含的校验规则进行校验,validate()返回一个valid,值为Boolean类型,用来判断执行成功/失败后的操作。