# GameGroup 组件设计文档
**项目名称**: GameGroup 前端系统
**文档版本**: v1.0
**更新时间**: 2026-01-28
---
## 📋 目录
- [1. 组件概述](#1-组件概述)
- [2. 基础组件](#2-基础组件)
- [3. 业务组件](#3-业务组件)
- [4. 布局组件](#4-布局组件)
- [5. 组件通信](#5-组件通信)
- [6. 组件性能优化](#6-组件性能优化)
---
## 1. 组件概述
### 1.1 组件分类
```
组件层级
├── 布局组件 (Layout)
│ ├── MainLayout # 主布局
│ ├── EmptyLayout # 空白布局
│ └── AuthLayout # 认证布局
│
├── 容器组件 (Container)
│ ├── AppHeader # 顶部导航
│ ├── AppSidebar # 侧边栏
│ └── AppFooter # 页脚
│
├── 业务组件 (Business)
│ ├── UserCard # 用户卡片
│ ├── GroupCard # 小组卡片
│ ├── GameCard # 游戏卡片
│ ├── AppointmentCard # 预约卡片
│ └── HonorBadge # 荣誉徽章
│
└── 基础组件 (Base)
├── Button # 按钮
├── Input # 输入框
├── Select # 下拉选择
├── Modal # 弹窗
├── Drawer # 抽屉
├── Table # 表格
├── Form # 表单
├── Upload # 上传
└── ...
```
### 1.2 命名规范
- **单文件组件**: PascalCase (UserCard.vue)
- **组件注册**: PascalCase
- **props**: camelCase
- **events**: kebab-case
### 1.3 组件结构
```vue
```
---
## 2. 基础组件
### 2.1 Button 按钮
#### 功能特性
- 支持多种类型 (primary, secondary, text, danger)
- 支持多种尺寸 (large, medium, small)
- 支持图标
- 支持加载状态
- 支持禁用状态
- 支持按钮组
#### API
```typescript
interface ButtonProps {
type?: 'primary' | 'secondary' | 'text' | 'danger'
size?: 'large' | 'medium' | 'small'
icon?: string
loading?: boolean
disabled?: boolean
long?: boolean /* 长按钮,宽度100% */
nativeType?: 'button' | 'submit' | 'reset'
}
interface ButtonEmits {
click: [event: MouseEvent]
}
```
#### 使用示例
```vue
```
#### 实现代码
```vue
```
---
### 2.2 Input 输入框
#### 功能特性
- 支持前缀/后缀图标
- 支持清除按钮
- 支持字数统计
- 支持搜索模式
- 支持多行文本域
- 支持密码显示切换
#### API
```typescript
interface InputProps {
modelValue: string | number
type?: 'text' | 'password' | 'textarea' | 'search'
placeholder?: string
disabled?: boolean
clearable?: boolean
showPassword?: boolean
prefixIcon?: string
suffixIcon?: string
maxlength?: number
rows?: number /* textarea行数 */
size?: 'large' | 'medium' | 'small'
}
interface InputEmits {
'update:modelValue': [value: string]
'change': [value: string]
'focus': [event: FocusEvent]
'blur': [event: FocusEvent]
'clear': []
}
```
#### 使用示例
```vue
```
---
### 2.3 Modal 弹窗
#### 功能特性
- 支持自定义头部/底部
- 支持多种尺寸
- 支持全屏
- 支持遮罩层点击关闭
- 支持键盘ESC关闭
- 支持嵌套弹窗
#### API
```typescript
interface ModalProps {
visible?: boolean
title?: string
width?: string | number
fullscreen?: boolean
top?: string /* 距离顶部距离 */
modal?: boolean /* 是否显示遮罩 */
lockScroll?: boolean /* 是否锁定滚动 */
closeOnClickModal?: boolean
closeOnPressEscape?: boolean
showClose?: boolean
beforeClose?: (done: () => void) => void
}
interface ModalEmits {
'update:visible': [value: boolean]
open: []
opened: []
close: []
closed: []
}
interface ModalSlots {
header?: () => VNode
default?: () => VNode
footer?: () => VNode
}
```
#### 使用示例
```vue
这是一段内容
```
---
### 2.4 Card 卡片
#### 功能特性
- 支持阴影配置
- 支持边框配置
- 支持图片封面
- 支持悬停效果
- 支持可点击
#### API
```typescript
interface CardProps {
shadow?: 'always' | 'hover' | 'never'
bodyStyle?: object /* body样式 */
header?: string /* 标题 */
cover?: string /* 封面图 */
clickable?: boolean /* 可点击 */
hoverable?: boolean /* 悬停效果 */
}
interface CardSlots {
header?: () => VNode
default?: () => VNode
cover?: () => VNode
extra?: () => VNode /* 头部额外内容 */
}
```
#### 使用示例
```vue
卡片内容
卡片内容
卡片标题
卡片描述
```
---
### 2.5 Table 表格
#### 功能特性
- 支持自定义列
- 支持排序
- 支持选择
- 支持分页
- 支持加载状态
- 支持展开行
#### API
```typescript
interface TableProps {
data: T[]
columns: Column[]
stripe?: boolean /* 斑马纹 */
border?: boolean
showHeader?: boolean
highlightCurrentRow?: boolean
rowKey?: string | ((row: T) => string)
defaultSort?: { prop: string; order: 'ascending' | 'descending' }
}
interface Column {
prop: string
label: string
width?: number | string
minWidth?: number | string
align?: 'left' | 'center' | 'right'
sortable?: boolean
fixed?: 'left' | 'right'
formatter?: (row: any, column: Column, value: any) => string
slots?: { default: (scope: { row: any; $index: number }) => VNode }
}
```
#### 使用示例
```vue
```
---
## 3. 业务组件
### 3.1 UserCard 用户卡片
#### 功能特性
- 显示用户头像、昵称、角色
- 显示会员状态
- 显示在线状态
- 支持快捷操作
- 支持点击跳转
#### API
```typescript
interface UserCardProps {
user: {
id: string
username: string
nickname?: string
avatar: string
role?: string
isMember?: boolean
isOnline?: boolean
}
showActions?: boolean /* 显示操作按钮 */
clickable?: boolean /* 可点击 */
}
interface UserCardEmits {
click: [user: User]
chat: [userId: string]
}
```
#### 使用示例
```vue
```
---
### 3.2 GroupCard 小组卡片
#### 功能特性
- 显示小组头像、名称
- 显示成员数量
- 显示用户角色
- 支持快速加入
- 显示小组标签
#### API
```typescript
interface GroupCardProps {
group: {
id: string
name: string
avatar: string
description?: string
currentMembers: number
maxMembers: number
myRole?: 'owner' | 'admin' | 'member'
tags?: string[]
}
showJoinButton?: boolean
showMemberCount?: boolean
}
interface GroupCardEmits {
click: [group: Group]
join: [groupId: string]
}
```
---
### 3.3 GameCard 游戏卡片
#### 功能特性
- 显示游戏封面
- 显示游戏名称
- 显示游戏类型标签
- 显示人数范围
- 显示平台信息
#### API
```typescript
interface GameCardProps {
game: {
id: string
name: string
coverUrl: string
description?: string
tags: string[]
minPlayers: number
maxPlayers: number
platform: string
}
showCover?: boolean
showTags?: boolean
clickable?: boolean
}
```
---
### 3.4 AppointmentCard 预约卡片
#### 功能特性
- 显示预约时间
- 显示参与人数
- 显示游戏信息
- 显示预约状态
- 支持快速加入/退出
#### API
```typescript
interface AppointmentCardProps {
appointment: {
id: string
title: string
startTime: string
endTime: string
currentParticipants: number
maxParticipants: number
status: 'open' | 'full' | 'cancelled' | 'finished'
game: Game
isParticipant: boolean
isCreator: boolean
}
showActions?: boolean
}
interface AppointmentCardEmits {
join: [appointmentId: string]
leave: [appointmentId: string]
}
```
---
### 3.5 HonorBadge 荣誉徽章
#### 功能特性
- 显示荣誉图标
- 显示荣誉名称
- 显示获得者
- 动画效果
#### API
```typescript
interface HonorBadgeProps {
honor: {
id: string
title: string
type: 'YEARLY' | 'MONTHLY' | 'WEEKLY'
year?: number
icon?: string
}
size?: 'small' | 'medium' | 'large'
animated?: boolean
}
```
---
## 4. 布局组件
### 4.1 MainLayout 主布局
#### 功能特性
- 响应式布局
- 侧边栏折叠
- 顶部导航栏
- 内容区域
#### 结构
```
┌─────────────────────────────────────────┐
│ AppHeader │
├──────────┬──────────────────────────────┤
│ │ │
│ │ │
│ App │ RouterView │
│ Sidebar │ │
│ │ │
│ │ │
└──────────┴──────────────────────────────┘
```
#### 使用示例
```vue
```
---
### 4.2 AppHeader 顶部导航
#### 功能特性
- Logo展示
- 导航菜单
- 搜索框
- 用户信息
- 消息通知
#### API
```typescript
interface AppHeaderProps {
showLogo?: boolean
showSearch?: boolean
showNotification?: boolean
fixed?: boolean
}
```
---
### 4.3 AppSidebar 侧边栏
#### 功能特性
- 可折叠
- 菜单导航
- 用户信息卡片
- 小组快捷入口
#### API
```typescript
interface AppSidebarProps {
collapsed?: boolean
menuItems: MenuItem[]
}
interface MenuItem {
path: string
icon?: string
label: string
children?: MenuItem[]
}
```
---
## 5. 组件通信
### 5.1 Props / Emits
父子组件通信:
```vue
```
### 5.2 Provide / Inject
跨层级组件通信:
```vue
```
### 5.3 Slots
插槽传递:
```vue
自定义标题
默认内容
```
### 5.4 Event Bus
兄弟组件通信:
```typescript
// utils/eventBus.ts
import { ref } from 'vue'
type EventBus = Record
const bus = ref({})
export function useEventBus() {
const emit = (event: string, ...args: any[]) => {
if (bus.value[event]) {
bus.value[event].forEach((fn) => fn(...args))
}
}
const on = (event: string, callback: Function) => {
if (!bus.value[event]) {
bus.value[event] = []
}
bus.value[event].push(callback)
}
const off = (event: string, callback?: Function) => {
if (!callback) {
delete bus.value[event]
} else {
bus.value[event] = bus.value[event].filter((fn) => fn !== callback)
}
}
return { emit, on, off }
}
```
---
## 6. 组件性能优化
### 6.1 懒加载
动态导入组件:
```vue
```
### 6.2 KeepAlive
缓存组件状态:
```vue
```
### 6.3 v-once
静态内容只渲染一次:
```vue
{{ staticTitle }}
{{ staticContent }}
```
### 6.4 computed缓存
使用计算属性缓存结果:
```vue
```
### 6.5 虚拟滚动
长列表使用虚拟滚动:
```vue
{{ item.name }}
```
---
## 7. 组件测试
### 7.1 单元测试
```typescript
// components/base/Button/__tests__/Button.test.ts
import { mount } from '@vue/test-utils'
import { describe, it, expect } from 'vitest'
import Button from '../Button.vue'
describe('Button', () => {
it('renders properly', () => {
const wrapper = mount(Button, {
slots: { default: 'Click me' }
})
expect(wrapper.text()).toBe('Click me')
})
it('emits click event', async () => {
const wrapper = mount(Button)
await wrapper.trigger('click')
expect(wrapper.emitted('click')).toBeTruthy()
})
it('does not emit click when disabled', async () => {
const wrapper = mount(Button, {
props: { disabled: true }
})
await wrapper.trigger('click')
expect(wrapper.emitted('click')).toBeFalsy()
})
})
```
---
## 8. 总结
本组件设计文档确保:
- ✅ **可复用性**: 组件可在多个场景使用
- ✅ **可维护性**: 清晰的代码结构和文档
- ✅ **一致性**: 统一的API和设计风格
- ✅ **类型安全**: 完整的TypeScript支持
- ✅ **性能优化**: 合理的优化策略
---
**文档维护**: 随组件库演进持续更新
**最后更新**: 2026-01-28