序文
プロジェクトの開発プロセス中に、手の速度が速い場合、
vue
コンポーネントのクリック イベントが連続して複数回トリガーされることが判明しました。この質問により、予期しない問題が生じる可能性がありますbug
。
以下にいくつかの解決策を示します。
1. js アンチシェイクと Vue カスタム命令を使用して実現します。
コードは以下のように表示されます:
<template>
<div>
<div v-debounce="search" style="width: 100px;height: 100px;background-color: yellow;">快速连续点击</div>
</div>
</template>
<script>
export default {
name: 'debounce',
data () {
return {
msg: 'Welcome to Your Vue.js App',
text: '',
count: 1
}
},
directives: {
debounce: {
inserted: function (el, binding) {
let timer
el.addEventListener('click', () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
binding.value()
}, 300)
})
}
}
},
methods: {
search () {
// 实际要进行的操作
this.count++
console.log('count is:' + this.count)
}
}
}
</script>
2. クリック状態を制御する
変数 (例: isLock
) を定義してボタンのプロパティを制御しdisable
、ユーザーが短時間にボタンを複数回クリックすることを防ぎます。
次のように進めます。
- まず、ボタンをクリックできるように変数の
isLock
属性値を設定します ( )false
disable: true
- ユーザーがクリックすると、すぐにボタンをクリックできないように設定します (
disable: false
)- イベントの実行または対応する間隔を待った後、ボタンをクリック可能な状態に戻します。
コードは次のとおりです(例)。
<el-button @click="clickBtn" :disable="isLock">按钮</el-button>
export default{
data(){
return {
isLock: false, // 控制按钮的disable属性
}
},
methods: {
clickBtn(){
// 设置按钮不可点击(disable: false)
this.isLock = true
// 执行耗时间的代码或事件请求等....
// 等待事件执行完或者相应的间隔时间后,恢复按钮为可点击状态
setTimeout(() => {
this.isLock = false
}, 2000)
}
}
}
3. デバウンス機能のみを使用する
common.js
パブリックメソッドファイルを定義する
/**
* 函数防抖
*/
export function debounce(fn, delay) {
// 记录上一次的延时器
var timer = null;
var delay = delay || 200;
return function() {
var args = arguments;
var that = this;
// 清除上一次延时器
clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(that,args)
}, delay);
}
}
vue
コンポーネントの紹介common.js
import {
debounce} from '../common/common.js'
vue
コンポーネントコード
<template>
<div>
<div @click="handleClick" style="width: 100px;height: 100px;background-color: yellow;">快速连续点击</div>
</div>
</template>
<script>
import {
debounce,throttle} from '../common/common.js'
export default{
data() {
return {
}
},
methods:{
handleClick:debounce(function(){
console.log('业务逻辑')
},300),
}
}
</script>
<style>
</style>
要約する
既存の問題
方法一
、方法三
2つの方法の問題
方法一
,方法三
この 2 つの方法の中心となるロジックはdebounce
アイデアを使用することですが、使用方法が異なります。
これら 2 つの方法は、基本的にクリックの繰り返しを防止するというニーズを満たすことができますが、実際のテストでは、遅延時間を制御するのが容易ではないことが判明しました。遅延時間が短く (<150ms)、素早いクリックでも複数のイベントがトリガーされる可能性があります。遅延時間が長い (>600 ミリ秒) 場合、ユーザーがクリックしてイベントをトリガーした後に明らかな遅延プロセスが発生し、ユーザー エクスペリエンスはあまり良くありません。
まず、達成したいことを定義しましょう。
- ユーザーがボタンを押すと、すぐにクリック イベントが発生します。
- ユーザーがボタンを素早く連続して押した場合、最初のクリック イベントのみがトリガーされます。
- ユーザーが中断することなく狂ったようにボタンをクリックすると (暴力的なテスト)、最初のイベントのみがすぐにトリガーされ、タイムアウト期間が経過しても、狂ったようにクリックしている間はイベントはトリガーされません。
解決
使用lodash
中debounce
;
コードは以下のように表示されます:
<template>
<div>
<div @click="handleClick" style="width: 100px;height: 100px;background-color: yellow;">快速连续点击</div>
</div>
</template>
<script>
import _ from "lodash"
export default {
methods: {
handleClick:_.debounce(function() {
//你的业务逻辑
console.log('执行业务逻辑1 ' + Math.random())
}, 1000, {
'leading': true, //在延迟开始前立即调用事件
'trailing': false, //在延时结束后不调用,保证事件只被触发一次
})
}
}
</script>
<style>
</style>
lodash
さらに、これら 2 つの属性に関する具体的な説明についてはdebounce
、lodash关键配置
の公式ドキュメントを参照してください。leading
trailing