el-form フォームに非同期検証がある場合、フォーム全体の検証を行うにはどうすればよいですか?

プロジェクトで element-ui が使用されている場合、フォーム機能を実装する必要がある場合、プログラミングには必ず element-ui の el-form フォームが使用されます。

プロローグ:

まず、el-form の公式ドキュメントを見てみましょう。 

メソッド名 説明する パラメータ
検証 フォーム全体を検証するためのメソッド。パラメータはコールバック関数です。このコールバック関数は検証が完了した後に呼び出され、検証が成功したかどうかと検証に失敗したフィールドの 2 つのパラメータが渡されます。コールバック関数が渡されない場合は、Promise が返されます。 関数(コールバック: 関数(ブール値、オブジェクト))

赤でマークされた 2 つの文は非常に重要です。

隠れた危険:

正式なメソッドができたので、フォームを送信する前に validate メソッドを使ってフォーム全体を検証し、次のような書き方をします。

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

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

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

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

↑↑↑↑多くの学生がフォームのロジックを検証する場合、上記のように書くことがありますが、まず el-form の validate メソッドを呼び出し、コールバック関数で valid を使用してフォームにエラーがあるかどうかを判定します。 validate メソッド フォームの送信を妨げるエラーがフォームにあるかどうかを判断します。

この書き方には「セキュリティ上のリスク」があります。

  1. el-formのルールフィールド検証ルールに非同期検証がない場合、上記のコードは同期実行され、validateメソッド呼び出し後に正しくhasErrorが取得できるので、このように書いても問題ありません。
  2. ただし、el-formのルールフィールド検証ルールに非同期検証(下部に説明)がある場合、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

解決する:

方法 1: フォーム送信ロジックをコールバック関数に直接組み込む

フォーム送信ロジックが多すぎると感じる場合は、別の関数を作成し、コールバック関数で呼び出してください。


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

});

方法 2: async/await を使用し、catch の組み合わせを試してフォーム検証を実行する

公式説明: validate メソッドがコールバック関数を渡さない場合、promise が返されますフォーム検証でエラーがなかった場合、validate 内でsolve(valid) が実行され、失敗した場合は、reject(valid) が実行されます (これの具体的な内部実装については、el-form ソース コードを参照してください)。このように、async/await と try catch の組み合わせをフォーム検証に使用できます

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

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

補足:非同期検証とは何ですか?

一部のシナリオでは、フォーム フィールドは検証のために入力ボックスの入力値をサーバーに渡すインターフェイスを呼び出す必要があります。サーバー側が検証を完了すると、検証結果が返されます。この状況は非同期検証です。

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"
        ]
    }
}

おすすめ

転載: blog.csdn.net/weixin_46422035/article/details/125596836