フォーム送信時はユーザーに操作させたくない
フォームの送信ボタンを押したときは二重にリクエストが飛ばないようにボタンを押せなくしたり、そもそも画面の項目に触れてほしくないので画面をロック状態にするようにしたい
以下は過去行ってた二重送信対応策(jQuery)
【JavaScript】フォーム等の送信ボタンに対する二重送信防止対応策 - Qiita
ElementUIのコンポーネントたちを使用して実現させる
今回はElementUI(Vue.jsのコンポーネントライブラリ)のFormコンポーネントとloadingコンポーネントを組み合わせて、フォームのリクエスト送信時に画面をロックさせる
サンプル
See the Pen Lock screen when sending By ElementUI by sola-msr (@sola-msr) on CodePen.
対応部分
サンプルでは**v-loading.fullscreen.lock
をボタン部分に追加し、送信時にローディング描写をON(true
)、送信完了(正常系レスポンス受け取り時)にOFF(false
)をセットしています。
上記の対応だけではまだ送信ボタンを押下することが出来る状態ですので、追加の対応としてフォーム全体を非活性化(disabled
)させるように、el-form
部分にdisabled
を追加し、これも送信時と送信完了時にON/OFFさせる**ようにしています。
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="120px" class="demo-ruleForm" :disabled="this.disabledForm">
<el-form-item label="Name" prop="name">
<el-input type="text" v-model="ruleForm.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="Password" prop="pass">
<el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="Confirm" prop="checkPass">
<el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="Activity zone" prop="region">
<el-select v-model="ruleForm.region" placeholder="Activity zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')" v-loading.fullscreen.lock="fullscreenLoading">Submit</el-button>
<el-button @click="resetForm('ruleForm')">Reset</el-button>
</el-form-item>
</el-form>
methods
で変数**fullscreenLoading
とdisabledForm
にtrue
/false
をセットする関数(openFullScreen()
とcloseFullScreen()
)を定義し、submitForm
関数**の中で各々のタイミングで呼び出すようにしてます。
// 略
methods: {
openFullScreen() {
this.fullscreenLoading = true;
this.disabledForm = true;
},
closeFullScreen() {
this.fullscreenLoading = false;
this.disabledForm = false;
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// ローディング描写とフォーム非活性化
this.openFullScreen();
// イメージしやすいようにあえて3秒間ローディング描写させるようにしてます
setTimeout(() => {
alert('submit!');
// ローディング描写とフォーム非活性化をそれぞれ解除
this.closeFullScreen();
}, 3000);
} else {
// ここでもcloseFullScreen()を実行したほうがいいかもしれません
console.log('error submit!!');
return false;
}
});
},
// 略
おわり
- ローディング描写中にさらにプログレスバーを表示させる方法を知りたい(切実)