Article Directory
foreword
During the project development process, it was found that in the case of fast hand speed,
vue
the component click event will be triggered multiple times in succession. This question can produce some unexpectedbug
.
Below we provide several solutions;
1. Use js anti-shake and Vue custom instructions to realize.
code show as below:
<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. Control the click state
Define a variable (such as: isLock
) to control disable
the properties of the button, thereby preventing the user from clicking the button multiple times in a short time
Proceed as follows:
- First set the variable
isLock
attribute valuefalse
to make the button clickable (disable: true
)- When the user clicks, immediately set the button to be unclickable (
disable: false
)- After waiting for the event to be executed or the corresponding interval, restore the button to the clickable state
The code is as follows (example):
<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. Only use the debounce function
define common.js
public method file
/**
* 函数防抖
*/
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
Component introductioncommon.js
import {
debounce} from '../common/common.js'
vue
component code
<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>
Summarize
existing problems
方法一
, 方法三
the problems of the two ways
方法一
, 方法三
The core logic of the two ways is to use debounce
the idea, but the way of use is different.
These two methods can basically meet the needs of preventing repeated clicks, but the actual test found that the delay time is not easy to control. If the delay time is short (<150ms) and quick clicks may still trigger multiple events. If the delay time is long (>600ms), there will be an obvious delay process after the user clicks to trigger the event, and the user experience is not very good.
First, let's define what we want to achieve.
- The click event fires immediately when the user presses the button.
- Only the first click event is triggered when the user presses the button in rapid succession.
- The user clicks the button crazily without interruption (violent test), and only the first event is triggered immediately, and the event will not be triggered during the frantic click, even if the timeout period has passed.
solution
lodash
in use debounce
;
code show as below:
<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
What debounce
's 关键配置
more leading
, you can refer to the official lodashtrailing
documentation for specific explanations about these two attributes .