当前位置: 首页 > news >正文

Vue3 + Element Plus 防止按钮重复点击的解决方案

在 Vue3 和 Element Plus 项目中,防止按钮重复点击是一个常见的需求,特别是在表单提交、支付等场景下。以下是几种实现方式:

1. 使用 Element Plus 的 loading 状态

Element Plus 的按钮组件本身就支持 loading 状态,这是最简单的方式:

vue

复制

下载

<template><el-button type="primary" :loading="loading" @click="handleSubmit">提交</el-button>
</template><script setup>
import { ref } from 'vue';const loading = ref(false);const handleSubmit = async () => {loading.value = true;try {// 执行异步操作await submitForm();} finally {loading.value = false;}
};
</script>

2. 自定义指令实现防重复点击

可以创建一个全局指令来实现防重复点击:

javascript

复制

下载

// directives.js
import { Directive } from 'vue';export const preventReClick: Directive = {mounted(el, binding) {el.addEventListener('click', () => {if (!el.disabled) {el.disabled = true;setTimeout(() => {el.disabled = false;}, binding.value || 2000);}});}
};// main.js
import { preventReClick } from './directives';
app.directive('prevent-reclick', preventReClick);

使用方式:

vue

复制

下载

<el-button v-prevent-reclick="1000" @click="handleClick">提交</el-button>

3. 使用装饰器(适用于组合式 API)

可以创建一个可组合函数来防止重复点击:

javascript

复制

下载

// composables/usePreventReClick.js
import { ref } from 'vue';export function usePreventReClick() {const isClicking = ref(false);const preventReClick = async (fn) => {if (isClicking.value) return;isClicking.value = true;try {await fn();} finally {isClicking.value = false;}};return {isClicking,preventReClick};
}

ts,usePreventReClick.ts

import { ref } from "vue";type AsyncFunction = () => Promise<void>;/*** 防止重复点击 hook* @returns*/
export function usePreventReClick() {const isClicking = ref(false);const preventReClick = async (fn: AsyncFunction) => {if (isClicking.value) {return;}isClicking.value = true;try {await fn();} finally {isClicking.value = false;}};return {isClicking,preventReClick};
}

使用方式:

vue

复制

下载

<script setup>
import { usePreventReClick } from './composables/usePreventReClick';const { isClicking, preventReClick } = usePreventReClick();const handleSubmit = () => {preventReClick(async () => {// 执行提交逻辑await submitForm();});
};
</script><template><el-button :loading="isClicking" @click="handleSubmit">提交</el-button>
</template>

4. 封装高阶组件

如果需要更复杂的控制,可以封装一个高阶组件:

vue

复制

下载

<!-- PreventReClickButton.vue -->
<template><el-button v-bind="$attrs" :loading="loading" @click="handleClick"><slot></slot></el-button>
</template><script setup>
import { ref } from 'vue';const props = defineProps({onClick: {type: Function,required: true},delay: {type: Number,default: 1000}
});const loading = ref(false);const handleClick = async () => {if (loading.value) return;loading.value = true;try {await props.onClick();} finally {setTimeout(() => {loading.value = false;}, props.delay);}
};
</script>

使用方式:

vue

复制

下载

<PreventReClickButton type="primary" :onClick="submitForm"
>提交
</PreventReClickButton>

总结

以上方法各有优缺点,根据项目需求选择:

  1. 简单场景:直接使用 Element Plus 的 loading 状态

  2. 全局控制:使用自定义指令

  3. 组合式 API:使用可组合函数

  4. 复杂组件:封装高阶组件

http://www.xdnf.cn/news/752671.html

相关文章:

  • LabVIEW多按键自动化检测系统
  • 03 APP 自动化-定位元素工具元素定位
  • LabVIEW双光子显微镜开发
  • lidar和imu的标定(四)小结
  • Rust 学习笔记:自定义构建和发布配置
  • Linux 内核中 skb_dst_drop 的深入解析:路由缓存管理与版本实现差异
  • MySql(十三)
  • 测量3D翼片的距离与角度
  • Spring MVC参数绑定终极手册:单多参/对象/集合/JSON/文件上传精讲
  • MATLAB实战:传染病模型仿真实现
  • 刚出炉热乎的。UniApp X 封装 uni.request
  • 鸿蒙OSUniApp离线优先数据同步实战:打造无缝衔接的鸿蒙应用体验#三方框架 #Uniapp
  • 一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (一)
  • 43. 远程分布式测试实现
  • CppCon 2014 学习: C++ Test-driven Development
  • 【C/C++】面试基础题目收集
  • 使用ReactNative加载HarmonyOS Svga动画
  • 西瓜书第十一章——降维与度量学习
  • π0论文阅读
  • 16-前端Web实战(Tlias案例-部门管理)
  • WEBSTORM前端 —— 第3章:移动 Web —— 第4节:移动适配-VM
  • Java函数式编程(上)
  • 【小沐杂货铺】基于Three.JS绘制太阳系Solar System(GIS 、WebGL、vue、react,提供全部源代码)第2期
  • Python UV 环境下的 PyKDL 运动学库安装
  • CSS篇-5
  • docker、ctr、crictl命令简介与使用
  • 基于Python与本地Ollama的智能语音唤醒助手实现
  • 无标注数据如何提升LLM推理能力?熵最小化 提升LLM自信度
  • 概念篇:软件测试
  • 基于springboot的益智游戏系统的设计与实现