4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.jsでいい感じに非同期の連投防止したい

Last updated at Posted at 2019-10-18

Vue.jsで連投防止するのに、個人的に楽なやり方ができたのでメモ。連打しないでほしいね。

とりあえずブツ

以下のmixinを使う。

multipost_avoidable.js
export default {
  data() {
    return {
      isPosting: false
    };
  },
  methods: {
    beginPost() {
      this.isPosting = true;
    },
    endPost() {
      this.isPosting = false;
    },
    async avoidMultipost(func) {
      if (this.isPosting) {
        return null;
      }
      this.beginPost();
      let res = await func();
      this.endPost();
      return res;
    }
  }
};

つかいかた

上のmixinを import して連投が起こりうる処理を avoidMultipost のコールバックとして渡す。送信後に画面遷移する場合などは、その処理もコールバック内に記述しましょう。 async function であることに注意。

Component.vue
// いろいろ省略
import MultipostAvoidable from "/path/to/mixin/multipost_avoidable";

export default {
  mixins: [MultipostAvoidable],
  methods: {
    async post() {
      this.avoidMultipost(async () => {
        // ここに非同期の通信処理 ex.: await axios.post(/path, data)
      });
    }
  }
};

しくみ

単純ですが、data プロパティに isPosting というパラメータを持っておき avoidMultipost 内のコールバックの実行前後で、 isPosting の状態を切り替えています。 isPostingtrue の場合はコールバックを実行しないようにして連投を防止しています。

コンポーネント内で連投防止処理を書くときに毎回 this.beginPost(); this.endPost(); で囲むのがしんどかったり、書き忘れるのが怖いので、デコレータみたいな感じにした。

投稿と同時に Button 要素を無効にしたいとかいう場合は該当要素に :disabled="isPosting" とかしてあげればいいと思います。

4
8
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
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?