Button组件设计
概述
Button 组件是本组件库中最基础且最重要的交互组件之一。它不仅提供了丰富的样式和交互功能,更重要的是体现了我们组件库的整体设计理念:关注点分离和逻辑抽象。
Button 组件的设计充分运用了我们自研的 useClassComputed 和 useColorComputed Hooks,将复杂的样式逻辑从组件本身剥离,使组件更加轻量且易于维护。
设计理念
分层架构
Button 组件严格按照三层架构设计:
- 结构层 (button.vue) - 负责组件的 DOM 结构和基本布局
- 逻辑层 (computedStyle.ts) - 通过 Hooks 处理复杂的响应式计算
- 表现层 (button.scss) - 定义组件的视觉呈现和样式规则
这种分离使得各层职责明确,便于维护和扩展。
逻辑抽象
Button 组件将复杂的逻辑抽象为两个核心 Hooks:
useClassComputed - 处理动态类名生成 useColorComputed - 处理颜色计算 这种设计使得组件本身只需要声明所需逻辑,而具体的计算由 Hooks 完成。
核心功能设计
Props 结构化设计
为了提高可维护性和可读性,我们将 Button 的 props 按照功能划分为多个逻辑组:
// 类型相关 props
const buttonTypeProps = {
type: {
type: String as PropType<'' | 'primary' | 'success' | 'warning' | 'danger' | 'info'>,
default: 'default' as const,
},
size: {
type: String as PropType<'supersmall' | 'small' | 'medium' | 'large' | 'superbig'>,
default: 'medium',
},
}
// 样式相关 props
const buttonStyleProps = {
rounded: { type: Boolean, default: false },
circular: { type: Boolean, default: false },
plain: { type: Boolean, default: false },
}
// 颜色相关 props
const buttonColorProps = {
colorBackground: { type: String, default: '' },
colorText: { type: String, default: '' },
colorBorder: { type: String, default: '' },
}
// 行为相关 props
const buttonBehaviorProps = {
disabled: { type: Boolean, default: false },
nativeType: {
type: String as PropType<'button' | 'submit' | 'reset'>,
default: 'button',
},
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
useClassComputed 的应用
Button 组件充分利用了 useClassComputed Hook 来处理动态类名的生成。在 useButtonStyle 函数中:
const btnClass = useClassComputed<ButtonProps>({
baseClass: 'my-btn',
propClasses: {
type: props.type === '' ? 'default' : props.type ?? 'default',
size: props.size ?? 'medium'
},
flagClasses: {
rounded: props.round,
circular: props.circle,
disabled: props.disabled,
plain: props.plain,
iconOnly: props.iconOnly,
}
})2
3
4
5
6
7
8
9
10
11
12
13
14
这种设计带来了以下优势:
- 统一的命名规范(BEM-like)
- 响应式的类名更新
- 高度可维护性和扩展性
useColorComputed 的应用
Button 组件使用 useColorComputed Hook 来处理自定义颜色的计算:
const customStyle = useColorComputed({
colorBackground: props.colorBg,
colorText: props.colorText,
colorBorder: props.colorBorder,
plain: props.plain,
isHovered: isHovered,
isActive: isActive,
disabled: props.disabled,
type: props.type
})2
3
4
5
6
7
8
9
10
样式系统设计
BEM 命名规范
Button 组件采用 BEM 命名规范,确保类名语义清晰:
· 基础类名:.my-btn · 修饰符类名:.my-btn--primary, .my-btn--large, .my-btn--round
状态管理
通过 CSS 类名和伪类管理各种交互状态:
· 悬停状态 (:hover) · 激活状态 (:active) · 禁用状态 (.my-btn--disabled)
响应式设计
支持五种尺寸规格: · supersmall · small · medium (默认) · large · superbig 每种尺寸都有对应的内边距和字体大小定义。
交互设计
Button 组件支持完整的鼠标交互反馈:
- 鼠标悬停时改变样式
- 鼠标按下时提供激活反馈
- 禁用状态下阻止交互并提供视觉反馈 通过 Vue 的响应式系统和事件处理机制,我们实现了这些交互效果:
const isHovered = ref(false);
const isActive = ref(false);
const onMouseOver = () => { isHovered.value = true; };
const onMouseOut = () => { isHovered.value = false; isActive.value = false; };
const onMouseDown = () => { isActive.value = true; };
const onMouseUp = () => { isActive.value = false; };2
3
4
5
6
7
可访问性设计
Button 组件考虑了可访问性设计:
· 使用语义化的 HTML 标签 · 支持原生 button 的 type 属性(button/submit/reset) · 正确处理 disabled 状态 · 提供足够的对比度和清晰的视觉反馈
扩展性设计
Button 组件具备良好的扩展性:
- 自定义标签支持:可通过 tag prop 渲染为不同 HTML 元素
- 自定义颜色:支持完全自定义背景、文字和边框颜色
- 图标支持:内置图标插槽支持和图标按钮模式
- 主题适配:通过 CSS 变量支持主题定制
性能优化
通过以下方式优化性能:
- 使用 computed 属性缓存计算结果
- 将复杂逻辑移至独立的 hooks 中
- 避免不必要的重新渲染
- 使用 Vue 3 Composition API 提高运行效率
设计价值
Button 组件作为组件库的基础组件,其设计体现了我们整体的设计哲学:
- 关注点分离:结构、样式、逻辑完全解耦
- 高度复用:通过 hooks 抽象通用逻辑
- 易于维护:清晰的代码结构和命名规范
- 可扩展性强:支持丰富的定制选项
- 一致性:遵循统一的设计语言和交互模式