UseElButton - 按钮
组件介绍
UseElButton 是基于 Element Plus 的
el-button进行二次封装的通用按钮组件,旨在简化按钮的使用流程、统一交互逻辑、减少重复开发成本。该组件兼容el-button原生所有属性,同时内置防抖、二次确认等高频业务能力,仅需通过配置项即可完成绝大部分按钮场景的开发,无需重复编写防抖、弹窗确认等业务逻辑代码,大幅提升中后台系统中按钮的开发效率和可维护性。
核心亮点
- 防抖能力内置化:组件内置防抖配置项,通过 extConfig.debounce 可灵活配置防抖延迟时间、是否立即执行,无需手动封装防抖函数,一键实现按钮点击防抖,适配高频点击(如提交、查询)场景。
- 二次确认一键启用:通过 extConfig.confirm.data 显式配置即可开启二次确认能力,内置弹框文案、数据格式处理等逻辑,支持字符串 / 数字 / 对象 / 数组等多类型数据传入,无需重复编写 ElMessageBox 相关代码。
- 原生属性全兼容:完全继承 el-button 的所有原生属性(如 type、size 等),仅新增扩展配置项,无需担心原生能力缺失,同时统一按钮基础样式和交互逻辑。
- 数据格式自动处理:针对二次确认场景,组件自动处理对象 / 数组类型数据的主键提取、数组 / 字符串转换、字段名追加 s 等格式转换,无需手动编写数据处理逻辑,适配不同后端接口参数要求。
- 事件逻辑智能兼容:自动检测外部是否绑定原生 @click 事件,若绑定则优先触发外部逻辑,未绑定则执行内置防抖 / 二次确认逻辑,兼顾自定义扩展与内置能力的灵活切换。
解决痛点
1.按钮防抖逻辑重复开发
- 痛点:中后台系统中提交、查询类按钮需频繁实现防抖逻辑,每个按钮都要手动引入防抖函数、配置延迟时间,不同页面防抖规则不统一,开发效率低且易遗漏。
- 解决方案:组件内置防抖配置项 extConfig.debounce,通过 delay(防抖时间)、immediate(是否立即执行)即可统一配置防抖规则,无需手动封装防抖函数,全局防抖逻辑可统一维护。
- 二次确认弹框代码冗余
- 痛点:删除、提交等高危操作按钮需添加二次确认弹框,每个按钮都要编写 ElMessageBox.confirm 逻辑,弹框标题、内容、数据处理逻辑分散在各页面,代码冗余且风格不统一。
- 解决方案:组件通过 extConfig.confirm 配置项一键开启二次确认,内置弹框标题、内容、数据格式处理逻辑,仅需配置 data(确认数据)、title(弹框标题)、content(弹框内容)即可,减少 80% 以上的二次确认重复代码。
- 二次确认数据格式处理复杂
- 痛点:二次确认场景中,需手动提取对象 / 数组的主键、转换数组为逗号分隔字符串、处理字段名复数(如 id 转 ids),不同开发者处理方式不同,易出现数据格式错误。
- 解决方案:组件内置数据格式自动处理逻辑,通过 dataKey(主键名)、toArray(是否转数组)、appendS(是否追加 s)配置项,自动完成主键提取、格式转换、字段名处理,无需手动编写数据处理代码,数据格式规则全局统一。
- 原生 click 事件与内置逻辑冲突
- 痛点:自定义按钮点击逻辑时,原生 @click 事件与组件内置防抖 / 二次确认逻辑易冲突,需手动判断触发时机,增加开发复杂度。
- 解决方案:组件自动检测外部是否绑定 @click 事件,若绑定则仅触发外部逻辑,未绑定则执行内置防抖 / 二次确认逻辑,兼顾自定义扩展与内置能力,无需手动处理事件冲突。
- 全局按钮样式 / 交互不一致
- 痛点:中后台系统多个页面的按钮,因无统一封装,样式污染、焦点状态异常等问题频发,且防抖、二次确认等交互逻辑分散,用户体验不一致。
- 解决方案:组件内置统一的样式兼容逻辑(如解决 el-button 链接样式焦点污染问题),同时统一防抖、二次确认等交互逻辑,既保证全局样式 / 交互一致性,又支持通过原生 el-button 属性覆盖默认样式,满足个性化需求。
- 无统一的扩展配置规范
- 痛点:按钮的防抖、二次确认等扩展能力无统一配置规范,不同页面配置方式各异,后期维护需逐个修改,维护成本高。
- 解决方案:组件定义了清晰的 ExtConfig 接口,统一防抖、二次确认的配置项规范,所有扩展能力通过 extConfig 配置项集中管理,配置结构统一,后期调整扩展规则仅需修改组件核心逻辑,无需逐个页面适配。
使用案例
原生 + 防抖
二次确认
Types
js
import type { ExtractPropTypes } from 'vue'
import componentProps from './props'
/**
* extConfig接口
*/
export interface ExtConfig {
/**
* 防抖配置项
*/
debounce: {
// 防抖时间
delay: number
// 是否立即开启防抖
immediate: boolean
}
/**
* 二次确认配置项
*/
confirm: {
// 二次确认数据 显式设置则开启二次确认,可为String、Number、Object、Array,无需传递数据则设置为null即可
data?: string | number | unknown
// 二次确认类型 同ElButton类型
type: string
// 二次确认数据主键key 对象或对象数组需要
dataKey: string
// 是否将以逗号分隔的字符串转换为数组 如:'1,2' => [1,2]
toArray: boolean
// 是否追加s到dataKey后面 如id => ids
appendS: boolean
// 二次确认弹框标题
title: string
// 二次确认弹框内容
content: string
}
}
/**
* props类型
*/
export type Props = ExtractPropTypes<typeof componentProps>
/**
* emits接口
*/
export interface Emits {
// 点击事件 默认带防抖
(e: 'onClick', value?: string | number | Record<string, unknown>): void
}ComponentProps
js
import type { PropType } from 'vue'
import type { ExtConfig } from './types'
/**
* 组件props
*/
export default {
/**
* 按钮文本 必传
*/
btnText: {
type: String,
required: true
},
/**
* 按钮类型 同ElButton类型,默认为primary
*/
type: {
type: String,
default: 'primary',
validator: (val: string) =>
[
'',
'default',
'primary',
'success',
'warning',
'danger',
'info'
].includes(val)
},
/**
* 扩展配置 如【防抖/二次确认】等
*/
extConfig: {
type: Object as PropType<ExtConfig>,
default: () => ({})
}
}DefaultExtConfig
js
import type { ExtConfig } from './types'
/**
* 默认扩展配置
*/
export default {
/**
* 防抖配置项 仅作用于@onClick事件,无需防抖则设置delay为0或使用@click事件即可。
* delay:防抖时间 默认500ms
* immediate:是否立即开启防抖 默认否
*/
debounce: { delay: 500, immediate: false },
/**
* 二次确认配置项
* data:二次确认数据 显式设置则开启二次确认,可为String、Number、Object、Array,无需传递数据则设置为null即可
* type:二次确认类型 默认danger,同ElButton类型
* dataKey:二次确认数据主键key 默认id,对象或对象数组需要
* toArray:是否将以逗号分隔的字符串转换为数组 如:'1,2' => [1,2]
* appendS: 是否追加s到dataKey后面 如id => ids
* title:二次确认弹框标题
* content:二次确认弹框内容
*/
confirm: {
type: 'danger',
dataKey: 'id',
toArray: false,
appendS: false,
title: '删除提示',
content: '确定将选择数据删除?'
}
} satisfies ExtConfigProps && Emits
js
const props = defineProps(componentProps)
const emits = defineEmits<Emits>()