場合によっては、ユーザーが短期間にボタンを繰り返しクリックすることを防ぐために、フロントエンドがバックエンドに複数のリクエストを繰り返し送信します。
1. ローディングを制御してローディングを設定するか、無効にします
最初に、ボタンにローディング効果を直接追加します。つまり、リクエストの前にローディングが true に設定され、繰り返しクリックされないようにリクエストの最後にローディングが false に設定されます。ただし、一部のリクエストは依然としてトリガーされる可能性があります。短時間内に複数回ダブルクリックしてください。
2. Vue カスタム命令を使用する
// 全局注册自定义指令
Vue.directive("resetClick", {
inserted(el, binding) {
el.addEventListener("click", () => {
if (!el.disabled) {
el.disabled = true;
el.style.cursor = "not-allowed";
setTimeout(() => {
el.disabled = false;
el.style.cursor = "pointer";
}, binding.value || 1000);
}
});
},
});
// 组件内使用
<el-button type="primary" v-resetClick="1000" @click="confirm">
确 定
</el-button>
3. デバウンス機能を使用する
ツール クラス util.js ファイルで手ぶれ補正機能を定義します (または、サードパーティのライブラリ throttle-debounce などを直接使用します)。
// 防抖debounce代码:
function debounce(fn, delay) {
let timeout = null // 创建一个标记用来存放定时器的返回值
return function (e) {
// 每当用户输入的时候把前一个 setTimeout clear 掉
clearTimeout(timeout)
// 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
timeout = setTimeout(() => {
fn.apply(this, arguments)
timeout = null
}, delay)
}
}
vue コンポーネントで使用される
<template>
<div>
<el-button type="primary" @click="handleClick">快速连续点击</el-button>
</div>
</template>
<script>
import { debounce } from '@/util/util.js'
export default {
data() {
return {}
},
methods: {
handleClick: debounce(() => {
console.log('删除操作等业务逻辑')
}, 500),
},
}
</script>
<style></style>
上記のどちらの方法にも問題があります
これら 2 つの方法は基本的に反復クリック防止のニーズを満たすことができますが、実際のテストでは、遅延時間を制御するのが難しいことがわかりました。遅延時間が短く (<150ms)、素早いクリックでも複数のクリックがトリガーされる可能性があります。イベント。遅延時間が長い (>600 ミリ秒) 場合、ユーザーがクリックしてイベントをトリガーした後に明らかな遅延プロセスが発生し、ユーザー エクスペリエンスはあまり良くありません。
まず、達成したいことを定義しましょう。
- ユーザーがボタンを押すと、すぐにクリック イベントが発生します。
- ユーザーがボタンを素早く連続して押した場合、最初のクリック イベントのみがトリガーされます。
- ユーザーが中断することなく狂ったようにボタンをクリックすると (暴力的なテスト)、最初のイベントのみがすぐにトリガーされ、タイムアウト期間が経過しても、狂ったようにクリックしている間はイベントはトリガーされません。
3. 最終的な解決策 lodash
npm i lodash -S
コンポーネントで使用される
<template>
<div>
<el-button type="primary" @click="handleClick">快速连续点击</el-button>
</div>
</template>
<script>
import { debounce } from 'lodash'
export default {
data() {
return {}
},
methods: {
handleClick: debounce(
() => {
console.log('删除操作等业务逻辑')
},
500,
{
leading: true, // 在延迟开始前立即调用事件
trailing: false, // 在延时结束后不调用,保证事件只被触发一次
},
),
},
}
</script>