vueに限らずフロント側の画面制御でボタン連打によるバックエンド側の多重リクエストが送信されることを防止する。
useFormのフラグによる制御
formのプロパティであるprocessingというフラグで判定する。
<script setup>
const form = useForm({
...
});
const submit = () => {
form.post('register');
};
</script>
<template>
<form @submit.prevent="submit">
...
<button
type="submit"
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing">
Register
</button>
...
</form>
</template>
axiosの場合(簡易フラグ)
一番簡単なのはフラグを用意してAPIの前後で囲む。
<script setup>
const isProcessing = ref(false);
const onClickUpdate = async () => {
// async/awaitではなくPromiseのthen/catch/finallyで実装するなら
// finallyでフラグをリセット。
isProcessing.value = true;
const { data, status } = await axios.post('update_data');
isProcessing.value = false;
};
</script>
<template>
<form @submit.prevent="submit">
...
<button
type="button"
@click="onClickUpdate"
:class="{ 'opacity-25': form.processing }"
:disabled="isProcessing">
Register
</button>
...
</form>
</template>
axiosのcancel機能で防止する
こちらは画面で防止するのではなくaxiosのリクエスト前処理で判定してエラーとするやり方。
参考サイト
上記サイトを参考に実装してみた感じ、ボタン連打による「同じ要求」は内部的に防げます。
リクエスト前処理、レスポンス受信後処理や
画面遷移での処理で同リクエスト判定用の変数の管理をする必要があり、
実装するに当たってある程度の設計スキルを要する。