项目中如果使用elementui的话,在需要实现表单功能时候,肯定会使用elementuielform表单编程

前序

首先,我们先来看一下el-form官方文档介绍: 

方法 说明 参数
validate 对整个表单进行校验的方法参数一个回调函数回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段若不传入回调函数,则会返回一个 promise Function(callback: Function(boolean, object))

标红的这两句话很重要。

隐患:

既然有了官方提供的方法,那么在提交表单前,再使用validate方法,对表单进行一个整体校验即可然后我们可能使用以下写法

let hasError = false; //表单是否报错的标志

//表单校验逻辑
this.$refs['ruleForm'].validate((valid) => {
    if (valid) {
        //表单有报错,将hasError置为true
        hasError = true;
    }
});

//如果表单有报错return,阻止 表单提交
if(hasError){
    return
}

//下方是校验通过后,表单提交的逻辑
//xxxxxxx

↑↑↑↑很多同学校验表单的逻辑时,可能就会像上面这种写法,先调用el-formvalidate方法,在回调函数通过valid判断表单是否有报错,在调用validate方法之后判断表单是否有报错来阻止表单提交

这种写法存在安全隐患的:

  1. el-formrules字段校验规则没有异步校验的情况下,上述代码同步执行的,在调用完validate方法之后是可以正确拿到hasError,这种情况下这样写没问题
  2. 但是如果el-formrules字段校验规则存在异步校验(最下面有解释)的情况,那么validate中的回调函数就是异步执行的,这时无论表单有没有报错都会走提交表单的逻辑↓↓↓↓↓        
let hasError = false; //表单是否有报错的标志

//表单校验逻辑(存在异步校验)
this.$refs['ruleForm'].validate((valid) => {
    if (valid) {
         
        //异步校验,异步执行,会在下面的代码if(hasError)之后执行,才能拿到异步执行结果正确hasError的值)

        //表单有报错,将hasError置为true
        hasError = true;
    }
});

//如果表单有报错,return,阻止 表单提交这里同步执行代码,会先执行这句,然而hasError在这一步永远是false)
if(hasError){
    return
}

//下方是校验通过后,表单提交的逻辑
//xxxxxxx

解决

方式一:将表提交逻辑直接放到回调函数

如果觉得表单提交逻辑太多就单独写一个函数在回调函数里面调用。


//表单校验逻辑(存在异步校验)
this.$refs['ruleForm'].validate((valid) => {
    
    if (!valid) {
         //表单校验有报错,return,代码不再往下执行
         return
    }
    
    //表单提交校验写到回调函数内
    //表单校验通过,进入表单提交逻辑
    //xxxxxxx

});

方式二:使用async/awaittry catch组合来进行表单校验

官方说明如果validate方法不传入回调函数,则会返回一个 promise。表单校验没有报错则在validate内部执行resolve(valid),失败则执行reject(valid) (这块具体内部实现看el-form源码)。这样可以使用async/awaittry catch组合来进行表单校验

async submitForm() {
    try {
      //调用表单的validate方法,执行表单校验
      await this.$refs['ruleForm'].validate()
    }catch(e) {
      //如果表单有报错,则进入catch,此时直接return不执行表单提交
      return
    }

    //表单校验通过,进入表单提交逻辑
    //xxxxxxx
}

补充:什么是异步校验?

有些场景的表单字段,需要调用接口,把某个input框的输入值传给服务端进行校验,服务端校验完成后把校验结果返回,这种情况就属于是异步校验。

el-form整体表单校验validate函数是等所有表单字段(包括异步校验的字段)都校验完成才执行validate中的回调函数,这就会存在我前面说的“安全隐患”。

例:

 <el-form-item label="名称:" prop="name">
    <el-input
          v-model.trim="formDetail.name"
          placeholder="1-20个字符"   
     />
</el-form-item>

data() {
    //校验规则
    formRules = {
        //name字段需要进行异步校验
        name: [
             validator: (rule, val, cb) => {
                  //发送ajax服务端进行校验
                  this.$http({
                      url: "/service/ajax-checkname",
                      method: "get",
                      data: {
                          name: val
                      }
                  }).then(res => {
                      let result = res.data;
                      if (!result.status) {
                         cb(result.message); //校验不通过,报错
                      } else {
                         cb(); //校验通过
                      }
                 });
            },
            trigger: "blur"
        ]
    }
}

原文地址:https://blog.csdn.net/weixin_46422035/article/details/125596836

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_43096.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注