4
2

More than 3 years have passed since last update.

【JavaScript】ElementUIのFormComponentを使用したフォームでリクエスト送信時、二重送信されないように画面をロックさせる

Last updated at Posted at 2020-02-28

フォーム送信時はユーザーに操作させたくない

フォームの送信ボタンを押したときは二重にリクエストが飛ばないようにボタンを押せなくしたり、そもそも画面の項目に触れてほしくないので画面をロック状態にするようにしたい

以下は過去行ってた二重送信対応策(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で変数fullscreenLoadingdisabledFormtrue/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;
          }
        });
      },
// 略

おわり

  • ローディング描写中にさらにプログレスバーを表示させる方法を知りたい(切実)

参考URL

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2