如何在 Vue.js 中实现链接点击节流(1500ms 防重复触发)

本文介绍一种不依赖 css `pointer-events`、也不滥用 `preventdefault()` 的 vue 前端节流方案:通过动态控制 `` 的 `event` 绑定与状态标记,实现点击后 1500ms 内禁用再次触发。

在 Vue 应用中,常需限制用户对导航链接(如 )的高频点击,例如防止重复提交或避免路由快速跳转导致的状态混乱。直接在 @click 中调用 e.preventDefault() 并配合 setTimeout 是常见误区——因为 preventDefault() 必须同步执行才能生效,而 setTimeout(() => e.preventDefault(), 1500) 实际上是在事件处理完成 1.5 秒后才执行,此时事件早已冒泡并完成导航,完全无效。

✅ 正确思路是:将“是否响应点击”这一逻辑前置到事件绑定层,而非事后拦截。Vue 提供了 :event 动态绑定能力,可让 在特定条件下不监听 click 事件。

✅ 推荐实现方式(Vue 2 / Vue 3 Options API)



? 关键点说明::event="isBlocked ? [] : ['click']:当 isBlocked 为 true 时, 不监听任何事件(包括 click),从源头禁用交互;@click 仅在 event 包含 'click' 时才会触发,因此无需 preventDefault();状态管理清晰,无副作用,兼容 SSR(服务端渲染)与无障碍访问(相比 pointer-events: none 更语义化)。

⚠️ 注意事项

  • 若使用 Vue 3 Composition API,可将 isBlocked 定义为 ref(false),setTimeout 中通过 .value = false 更新;
  • 避免在 @click 中混用 preventDefault() 和异步逻辑,违背事件生命周期;
  • 如需全局节流(如所有 router-link),可封装为自定义指令 v-throttle-click:1500,但本例推荐组件级状态控制,更可控、易测试。

此方案简洁、健壮且符合 Vue 响应式设计哲学:用数据驱动行为,而非强行阻断 DOM 事件流。