全局设置避免按钮连续点击触发重复接口请求
问题
连续点击同一按钮,会发送重复请求
解决
常规做法是给按钮添加 loading 点击状态,发送请求前设置为 true,请求结束后设置为 false。
缺点:每个按钮这样设置,代码重复而繁琐。
替代解决方案
在 main.js 中 全局设置点击事件防抖
// 防抖处理,避免按钮重复点击触发重复请求
const on = Vue.prototype.$on;
Vue.prototype.$on = function (event, func) {
let timer;
let newFunc = func;
if (event === "click") {
newFunc = function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, 1000);
};
}
on.call(this, event, newFunc);
};
注意事项
const on = Vue.prototype.$on
// 防抖处理
Vue.prototype.$on = function (event, func) {
let timer
let newFunc = func
if (event === 'click') {
newFunc = function () {
clearTimeout(timer)
timer = setTimeout(function () {
func.apply(this, arguments)
}, 1000)
}
}
on.call(this, event, newFunc)
}
最初是如上书写代码的,即 setTimeout 中是匿名函数,会导致点击后打印的参数为 undefined。但实际上应该为 PointerEvent。解决办法是将匿名函数改为箭头函数或者显式绑定 this 和 argumemts。 如下所示:
// 使用箭头函数修复
newFunc = function () {
clearTimeout(timer);
const context = this; // 保存当前 this(Vue 实例)
const args = arguments; // 保存当前 arguments
timer = setTimeout(() => {
func.apply(context, args); // 传递正确的 this 和参数
}, 1000);
};
因为匿名函数会改变 this 指向,即:
- 匿名函数有自己的
this,非严格模式下默认指向全局对象(window),严格模式下为undefined;这里的this不是 Vue 实例,导致func的上下文丢失,可能引发错误。
timer = setTimeout(function () {
func.apply(this, arguments); // 这里的 this 是全局对象或 undefined
}, 1000);
- 箭头函数没有自己的
this,会继承外层作用域的this。这里的this是newFunc被调用时的this,即 Vue 组件实例(事件处理函数默认绑定到 Vue 实例)。func的this能正确指向 Vue 实例,与原始事件处理逻辑一致。
timer = setTimeout(() => {
func.apply(this, arguments); // 这里的 this 是外层 newFunc 的 this
}, 1000);
arguments 参数的区别
- 匿名函数的
arguments是自身的参数,但setTimeout的回调默认没有参数,因此arguments为空。func接收不到事件参数(如Event对象),导致逻辑异常。
func.apply(this, arguments); // arguments 是 setTimeout 回调的参数(为空)
- 箭头函数没有自己的
arguments,因此arguments是外层newFunc的参数(即事件触发时的参数,如Event对象)。参数能正确传递给func,与原始逻辑一致。
func.apply(this, arguments); // arguments 是 newFunc 的参数
总结
| 特性 | 匿名函数 | 箭头函数 |
|---|---|---|
| this 指向 | 指向全局对象或 undefined | 正确指向 Vue 实例 |
| arguments 参数 | 参数丢失(arguments 为空) | 正确传递事件参数(如 Event 对象) |
| 功能正确性 | ❌ 上下文和参数错误,可能导致报错或异常行为 | ✅ 防抖逻辑正常,上下文和参数正确 |
参考链接
本文来自博客园,作者:shayloyuki,转载请注明原文链接:https://www.cnblogs.com/shayloyuki/p/18855091
posted on 2025-04-30 10:56 shayloyuki 阅读(69) 评论(0) 收藏 举报
浙公网安备 33010602011771号