Vue.jsで連投防止するのに、個人的に楽なやり方ができたのでメモ。連打しないでほしいね。
とりあえずブツ
以下のmixinを使う。
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 であることに注意。
// いろいろ省略
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 の状態を切り替えています。 isPosting が true の場合はコールバックを実行しないようにして連投を防止しています。
コンポーネント内で連投防止処理を書くときに毎回 this.beginPost(); this.endPost(); で囲むのがしんどかったり、書き忘れるのが怖いので、デコレータみたいな感じにした。
投稿と同時に Button 要素を無効にしたいとかいう場合は該当要素に :disabled="isPosting" とかしてあげればいいと思います。