プロジェクトで 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 メソッド フォームの送信を妨げるエラーがフォームにあるかどうかを判断します。
この書き方には「セキュリティ上のリスク」があります。
- el-formのルールフィールド検証ルールに非同期検証がない場合、上記のコードは同期実行され、validateメソッド呼び出し後に正しくhasErrorが取得できるので、このように書いても問題ありません。
- ただし、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"
]
}
}