vue防抖点击核心是按钮状态锁+请求生命周期管理,而非单纯延迟执行;需结合禁用按钮、try...finally恢复状态、请求级防重及服务端幂等保障。

Vue 中处理异步事件(如网络请求)时的防抖点击,核心不是单纯“延迟执行”,而是在请求生命周期内阻止重复触发。直接对 click 函数用防抖(debounce)容易误伤——比如用户点一次,防抖计时中接口已返回,但函数还没执行;或用户连点两次,只执行最后一次,却漏掉本该成功的第一次。真正有效的方案,是结合按钮状态锁 + 请求生命周期管理。
按钮状态锁:最直接、最可靠的基础防护
适用于绝大多数表单提交、按钮触发请求场景。原理简单:点击即锁定按钮,请求结束才解锁。
- 在
setup中用ref定义isSubmitting,绑定到按钮的:disabled和文字提示 - 点击处理函数开头加判断:
if (isSubmitting.value) return,避免状态未更新前的竞态(Vue 响应式更新异步) - 用
try...finally确保无论成功失败都恢复按钮状态,防止按钮永久置灰 - 示例逻辑:
const isSubmitting = ref(false) const handleSubmit = async () => { if (isSubmitting.value) return isSubmitting.value = true try { await api.submitOrder(formData) ElMessage.success('提交成功') } finally { isSubmitting.value = false } }
自定义防抖点击指令:复用性高,适合全局统一规范
当项目中多个按钮都需要类似逻辑(如“点击后禁用500ms”),封装为指令比每个地方写状态更清爽。注意它和纯 debounce 的区别:这里禁用是立即的,延时只是用于“释放”按钮,不延迟业务逻辑。

