Collapse 组件设计文档
概述
Collapse 组件是本组件库中用于折叠面板管理和展示的核心组件。它延续了我们组件库一贯的设计理念,采用"关注点分离"和"逻辑抽象"的原则,通过父子组件通信机制实现了一套完整且易用的折叠面板解决方案。
Collapse 组件专注于处理折叠面板的展开、收起操作,支持手风琴模式(Accordion)和多面板模式(Multi-panel),为用户提供了一套强大、灵活的折叠面板管理功能,支持动态切换、状态绑定和样式控制等功能。
设计理念
分层架构
Collapse 组件严格按照三层架构设计:
- 结构层 collapse.vue, collapseItem.vue - 负责组件的 DOM 结构和基本布局
- 逻辑层 collapse.vue 的逻辑部分 - 处理复杂的响应式计算和交互逻辑
- 表现层 collapse.scss - 定义组件的视觉呈现和样式规则
逻辑抽象
Collapse 组件将复杂的逻辑抽象为核心函数:
toggleItem- 处理折叠面板的展开/收起逻辑activeNames- 管理当前激活的面板名称列表或单个名称
这种设计使得组件本身只需要声明所需逻辑,而具体的计算由逻辑函数完成。
核心功能设计
Props 结构化设计
Collapse 组件的 props 设计简洁明了:
typescript
export const collapseProps = {
/** 当前激活的面板名称 */
modelValue: {
type: [String, Array] as PropType<string | string[]>,
default: () => [],
required: true,
},
/** 是否启用手风琴模式 */
accordion: {
type: Boolean,
default: false,
},
}CollapseItem 组件的 props 设计:
typescript
export const collapseItemProps = {
/** 唯一标识符 */
name: {
type: String,
required: true,
},
/** 面板标题 */
title: {
type: String,
default: '',
},
}这种设计提供了足够的灵活性,支持多种使用场景。
依赖注入机制
Collapse 组件通过 Vue 的依赖注入机制实现父子组件通信:
typescript
// 提供上下文
provide('collapse', {
activeNames,
toggleItem(name: string) {
// 手风琴模式逻辑
if (props.accordion) {
activeNames.value = activeNames.value === name ? '' : name;
} else {
// 多面板模式逻辑
const names = Array.isArray(activeNames.value) ? activeNames.value : [];
activeNames.value = names.includes(name)
? names.filter((n) => n !== name)
: [...names, name];
}
},
});
// 注入上下文
const collapse = inject('collapse') as {
activeNames: { value: string | string[] };
toggleItem: (name: string) => void;
};这种设计使得 CollapseItem 组件能够与其父级 Collapse 组件无缝协作。
样式系统设计
CSS 变量控制
Collapse 组件通过 CSS 变量实现样式控制:
--border-color- 边框颜色--header-bg-color- 面板头部背景颜色
布局系统
Collapse 组件支持灵活的布局控制:
- 块级布局 - 默认垂直排列
- 内边距控制 - 通过 SCSS 变量调整内边距
状态样式
Collapse 组件根据不同状态提供相应的样式:
- 默认状态 - 标准折叠面板样式
- 激活状态 - 展开时的高亮效果
- 悬停状态 - 鼠标悬停时的背景色变化
组件结构设计
整体结构
Collapse 组件的整体结构如下:
html
<div class="my-collapse">
<slot></slot>
</div>CollapseItem 组件的结构:
html
<div class="my-collapse-item">
<div class="my-collapse-item__header" @click="toggle">
<slot name="title">{{ title }}</slot>
</div>
<div v-show="isActive" class="my-collapse-item__content">
<slot></slot>
</div>
</div>组件层次
Collapse 组件包含两个主要部分:
- 容器 -
.my-collapse- 包裹整个折叠面板 - 子项 -
.my-collapse-item- 包含头部和内容区域 - 头部 -
.my-collapse-item__header- 折叠面板的标题部分 - 内容区域 -
.my-collapse-item__content- 折叠面板的内容部分
交互设计
面板切换
Collapse 组件支持动态切换面板:
typescript
function toggle() {
collapse.toggleItem(props.name);
}手风琴模式
在手风琴模式下,每次只能展开一个面板:
typescript
if (props.accordion) {
activeNames.value = activeNames.value === name ? '' : name;
}多面板模式
在多面板模式下,可以同时展开多个面板:
typescript
const names = Array.isArray(activeNames.value) ? activeNames.value : [];
activeNames.value = names.includes(name)
? names.filter((n) => n !== name)
: [...names, name];扩展性设计
Collapse 组件具备良好的扩展性:
- 数据绑定:通过 modelValue 属性实现双向数据绑定
- 模式切换:通过
accordion属性控制手风琴模式或多面板模式 - 插槽支持:通过 title 插槽自定义面板标题
- 样式定制:通过 SCSS 变量调整组件样式
样式细节
Collapse 组件在样式处理上有以下特点:
- 响应式设计:支持灵活的布局适配
- 一致性:与组件库其他组件保持样式一致性
- 动画效果:内容区域展开/收起时有平滑的过渡效果
- 无障碍设计:支持键盘导航和屏幕阅读器
性能优化
通过以下方式优化性能:
- 使用
computed属性缓存计算结果 - 将复杂逻辑移至独立的函数中
- 避免不必要的重新渲染
- 使用 Vue 3 Composition API 提高运行效率
- 合理使用事件监听器的添加和移除
设计价值
Collapse 组件延续了我们组件库的设计哲学:
- 关注点分离:结构、样式、逻辑完全解耦
- 高度复用:通过函数抽象通用逻辑
- 易于维护:清晰的代码结构和命名规范
- 可扩展性强:支持丰富的定制选项
- 一致性:与 Tabs、Card 等其他组件保持一致的设计语言