shayloyuki

勇气

 

全局设置避免按钮连续点击触发重复接口请求

问题

连续点击同一按钮,会发送重复请求

解决

常规做法是给按钮添加 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解决办法是将匿名函数改为箭头函数或者显式绑定 thisargumemts 如下所示:

// 使用箭头函数修复
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这里的 thisnewFunc 被调用时的 this,即 Vue 组件实例(事件处理函数默认绑定到 Vue 实例)。functhis 能正确指向 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 对象)
功能正确性 ❌ 上下文和参数错误,可能导致报错或异常行为 ✅ 防抖逻辑正常,上下文和参数正确

参考链接

  1. vue全局配置防抖和节流
  2. 匿名函数和普通函数的区别

posted on 2025-04-30 10:56  shayloyuki  阅读(69)  评论(0)    收藏  举报

导航