# Aether 设计系统 v2.3 > 基于 shadcn/ui 和书本纸张主题的完整前端设计规范 **版本**: 2.3.0 **最后更新**: 2025-11-18 --- ## 概述 本文档描述了 Aether 前端项目的设计系统,基于 shadcn/ui 和自定义主题构建。所有组件均已实现并在生产环境中使用。 ### 核心理念 1. **一致性优先** - 所有组件遵循统一的视觉语言和交互模式 2. **响应式设计** - 组件自适应不同屏幕尺寸(移动端、平板、桌面) 3. **可访问性** - 遵循 WCAG 2.1 标准,支持键盘导航和屏幕阅读器 4. **性能优化** - 轻量级组件,按需加载,优化渲染性能 5. **开发体验** - TypeScript 类型安全,清晰的 API 设计,完善的文档 ### 色彩体系 项目使用书本纸张主题色: - **book-cloth** - 书籍封面布料色 (#cc785c / #d4a27f) - **kraft** - 牛皮纸色 (#b97847 / #c9a26f) - **manilla** - 马尼拉纸色 (#e8ddc5 / #d4c5a9) - **cloud** - 云白色 (#f5f3ed / #2a2723) 详细配置见 [src/config/theme.ts](src/config/theme.ts) --- ## 技术栈 - **Vue 3** - Composition API - **TypeScript** - 类型安全 - **Tailwind CSS** - 原子化 CSS - **shadcn/ui** - 基础组件库 - **lucide-vue-next** - 图标库 - **Vite** - 构建工具 --- ## 主题系统 ### 主题配置 主题配置位于 [src/config/theme.ts](src/config/theme.ts),包含: ```ts export const theme = { colors: themeColors, // 颜色系统 spacing, // 间距系统(基于 8px 网格) radius, // 圆角系统 shadows, // 阴影系统 typography, // 字体系统 animations, // 动画系统 breakpoints, // 响应式断点 zIndex, // 层级管理 components: componentDefaults // 组件默认配置 } ``` ### CSS 变量 全局 CSS 变量定义在 `src/assets/index.css`,使用 HSL 色彩空间: ```css :root { --background: 0 0% 100%; --foreground: 20 14.3% 4.1%; --primary: 15 55% 58%; --border: 20 5.9% 90%; --muted: 60 4.8% 95.9%; --muted-foreground: 25 5.3% 44.7%; /* ... 更多变量 */ } .dark { --background: 20 14.3% 4.1%; --foreground: 0 0% 95%; --primary: 15 45% 68%; /* ... 暗色模式变量 */ } ``` --- ## 组件库 ### 基础组件 (shadcn/ui) 所有基础组件位于 [src/components/ui/](src/components/ui/): #### 布局组件 - **Card** - 卡片容器 - 变体:`default`、`outline`、`ghost`、`interactive` - **Separator** - 分隔线(水平/垂直) - **Tabs** - 选项卡容器 #### 表单组件 - **Button** - 按钮 - 变体:`default`、`destructive`、`outline`、`secondary`、`ghost`、`link` - 大小:`sm`、`md`、`lg`、`icon` - **Input** - 输入框 - **Textarea** - 多行文本框 - **Select** - 下拉选择框 - **Checkbox** - 复选框 - **Switch** - 开关 - **Label** - 表单标签 #### 反馈组件 - **Badge** - 徽章标签 - **Skeleton** - 骨架屏 - **Toast** - 消息提示 - **Dialog** - 对话框/模态框 - **Alert** - 警告提示 #### 数据展示 - **Table** 系列 - 表格组件 - Table、TableHeader、TableBody、TableRow、TableHead、TableCell - **Avatar** - 头像 - **Progress** - 进度条 --- ### 布局组件 (Layout Components) 位于 [src/components/layout/](src/components/layout/),所有组件支持从 `@/components/layout` 统一导入: ```ts import { PageHeader, PageContainer, Section, CardSection, Grid, StatCard } from '@/components/layout' ``` #### PageHeader 页面头部组件,支持标题、描述、图标和操作按钮。 **使用示例:** ```vue ``` **Props:** - `title: string` - 页面标题(必填) - `description?: string` - 页面描述 - `icon?: Component` - 图标组件 **Slots:** - `icon` - 自定义图标区域 - `actions` - 右侧操作按钮 --- #### PageContainer 页面容器,提供响应式的最大宽度和内边距。 **使用示例:** ```vue ``` **Props:** - `maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'` - 最大宽度(默认: '2xl') - `padding?: 'none' | 'sm' | 'md' | 'lg'` - 内边距(默认: 'md') --- #### Section 区块容器,用于分隔页面不同区域。 **使用示例:** ```vue ``` **Props:** - `title?: string` - 区块标题 - `description?: string` - 区块描述 - `spacing?: 'none' | 'sm' | 'md' | 'lg'` - 底部间距(默认: 'md') **Slots:** - `header` - 自定义头部 - `actions` - 右侧操作按钮 - `default` - 主内容 --- #### CardSection 卡片区块,基于 Card 组件的增强版。 **使用示例:** ```vue ``` **Props:** - `title?: string` - 卡片标题 - `description?: string` - 卡片描述 - `variant?: 'default' | 'elevated' | 'glass'` - 卡片样式(默认: 'default') - `padding?: 'none' | 'sm' | 'md' | 'lg'` - 内边距(默认: 'md') **Slots:** - `header` - 自定义头部 - `actions` - 头部右侧操作 - `default` - 主内容 - `footer` - 底部内容 --- #### Grid 响应式网格布局。 **使用示例:** ```vue ``` --- #### StatCard 统计卡片,用于展示关键指标。 **使用示例:** ```vue ``` --- #### ShellHeader (待废弃) 旧版页面头部组件,建议迁移到 `PageHeader`。 --- ### 业务组件 (Common Components) 位于 [src/components/common/](src/components/common/): #### 1. PageLayout 页面布局容器,集成标题、筛选、分页等功能。 **使用示例:** ```vue ``` **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `title` | `string` | - | 页面标题(必填) | | `subtitle` | `string` | - | 页面副标题 | | `showHeader` | `boolean` | `true` | 是否显示页面头部 | | `showBackButton` | `boolean` | `false` | 是否显示返回按钮 | | `maxWidth` | `'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'full'` | 内容最大宽度 | | `spacing` | `'tight' \| 'normal' \| 'relaxed'` | `'normal'` | 内容间距 | | `showFilters` | `boolean` | `false` | 是否显示筛选栏 | | `showPagination` | `boolean` | `false` | 是否显示分页 | **主要 Slots:** - `toolbar` - 页面右上角工具栏 - `headerExtra` - 头部额外内容 - `filters` - 筛选条件 - `filterLeft` / `filterRight` - 筛选栏左右插槽 - `default` - 主内容区 - `footer` - 页面底部 --- #### 2. DataTable 响应式数据表格,桌面端显示表格,移动端自动切换为卡片视图。 **使用示例:** ```vue ``` **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `columns` | `DataTableColumn[]` | - | 列配置(必填) | | `data` | `T[]` | - | 数据源(必填) | | `rowKey` | `string` | `'id'` | 行唯一标识字段 | | `loading` | `boolean` | `false` | 是否加载中 | | `clickable` | `boolean` | `false` | 是否可点击行 | | `emptyTitle` | `string` | `'暂无数据'` | 空状态标题 | **列配置(DataTableColumn):** ```ts interface DataTableColumn { key: string // 列标识(对应数据字段) label: string // 列标题 width?: string // 列宽度 align?: 'left' | 'center' | 'right' // 对齐方式 sortable?: boolean // 是否可排序 formatter?: (value: any, row: T, index: number) => string // 值格式化 headerClass?: string // 表头样式类 cellClass?: string // 单元格样式类 showOnMobile?: boolean // 是否在移动端显示(默认 true) } ``` **主要 Events:** - `rowClick(row, index)` - 行点击事件 - `sort(sortBy, sortOrder)` - 排序事件 **主要 Slots:** - `cell-{key}` - 自定义单元格内容(接收 `{ row, column, index, value }` 参数) - `mobile-card` - 自定义移动端卡片布局(接收 `{ row, index }` 参数) - `empty` - 自定义空状态 - `footer` - 表格底部内容 --- #### 3. SearchInput 智能搜索输入框,支持防抖、清除、建议列表。 **使用示例:** ```vue ``` **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `modelValue` | `string` | - | 输入值(必填) | | `placeholder` | `string` | `'搜索...'` | 占位符 | | `clearable` | `boolean` | `true` | 是否显示清除按钮 | | `loading` | `boolean` | `false` | 是否显示加载图标 | | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 大小 | | `suggestions` | `string[]` | `[]` | 搜索建议列表 | | `debounce` | `number` | `300` | 防抖延迟(毫秒) | --- #### 4. FilterBar 筛选栏容器,集成搜索和筛选条件。 **使用示例:** ```vue ``` --- #### 5. Pagination 分页组件,支持页码导航和每页数量选择。 **使用示例:** ```vue ``` **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `currentPage` | `number` | `1` | 当前页码 | | `pageSize` | `number` | `20` | 每页显示数量 | | `total` | `number` | `0` | 总记录数 | | `showPageSizeSelector` | `boolean` | `true` | 是否显示页面大小选择器 | | `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | 每页数量选项 | --- #### 6. EmptyState 空状态组件,支持多种类型和自定义内容。 **使用示例:** ```vue ``` **类型(type):** - `default` - 默认空状态 - `search` - 搜索无结果 - `filter` - 筛选无结果 - `error` - 加载错误 - `empty` - 空空如也 - `notFound` - 未找到资源 **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `type` | `EmptyStateType` | `'default'` | 空状态类型 | | `title` | `string` | - | 标题(自动根据类型设置) | | `description` | `string` | - | 描述(自动根据类型设置) | | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 大小 | | `actionText` | `string` | - | 操作按钮文本 | | `actionIcon` | `Component` | - | 操作按钮图标 | | `actionVariant` | `ButtonVariant` | `'default'` | 按钮变体 | --- #### 7. StatusBadge 状态徽章组件,用于显示不同状态。 **使用示例:** ```vue ``` **状态类型(status):** | 状态 | 颜色 | 图标 | 用途 | |------|------|------|------| | `success` | 绿色 | CheckCircle2 | 成功、完成、已激活 | | `error` | 红色 | XCircle | 错误、失败、已禁用 | | `warning` | 黄色 | AlertCircle | 警告、待审核、需注意 | | `info` | 蓝色 | Info | 信息、提示 | | `pending` | 灰色 | Clock | 待处理、排队中 | | `neutral` | 灰色 | Minus | 中性状态 | | `active` | 主题色 | CheckCircle2 | 活跃、在线 | | `inactive` | 灰色 | Minus | 未激活、离线 | **变体(variant):** - `solid` - 实心背景 - `soft` - 柔和背景(默认) - `outline` - 描边样式 --- #### 8. LoadingState 加载状态组件,支持多种加载样式。 **使用示例:** ```vue ``` **变体(variant):** - `spinner` - 旋转加载器(默认) - `skeleton` - 骨架屏 - `pulse` - 脉冲点动画 --- #### 9. ConfirmButton 带确认对话框的按钮组件,简化危险操作的确认流程。 **使用示例:** ```vue ``` **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `text` | `string` | - | 按钮文本 | | `variant` | `ButtonVariant` | `'default'` | 按钮样式 | | `size` | `ButtonSize` | `'md'` | 按钮大小 | | `icon` | `Component` | - | 图标组件 | | `disabled` | `boolean` | `false` | 是否禁用 | | `confirmTitle` | `string` | `'确认操作'` | 确认对话框标题 | | `confirmMessage` | `string` | `'确定要执行此操作吗?'` | 确认消息 | | `confirmType` | `'default' \| 'danger' \| 'warning'` | `'default'` | 确认类型 | | `requireConfirm` | `boolean` | `true` | 是否需要确认 | **Events:** - `click` - 不需要确认时触发 - `confirmed` - 确认后触发 - `cancelled` - 取消确认时触发 --- #### 10. ActionMenu 操作菜单下拉组件,用于集中展示多个操作选项。 **使用示例:** ```vue ``` **ActionMenuItem 接口:** ```ts interface ActionMenuItem { label?: string // 菜单项标签 icon?: Component // 图标 badge?: string | number // 徽章 variant?: 'default' | 'destructive' // 样式变体 disabled?: boolean // 是否禁用 separator?: boolean // 是否为分隔线 onClick?: () => void | Promise // 点击回调 } ``` **主要 Props:** | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `items` | `ActionMenuItem[]` | - | 菜单项列表(必填) | | `triggerText` | `string` | - | 触发按钮文本 | | `triggerIcon` | `Component` | - | 触发按钮图标 | | `triggerVariant` | `ButtonVariant` | `'outline'` | 触发按钮样式 | | `triggerSize` | `ButtonSize` | `'sm'` | 触发按钮大小 | | `showChevron` | `boolean` | `true` | 是否显示下拉箭头 | | `placement` | `'bottom-start' \| 'bottom-end' \| 'top-start' \| 'top-end'` | `'bottom-end'` | 菜单位置 | --- ## 工具函数 (Composables) 位于 [src/composables/](src/composables/) ### useBreakpoints 响应式断点检测,用于实现响应式布局。 ```ts import { useBreakpoints } from '@/composables/useBreakpoints' const { windowWidth, // 窗口宽度 isSm, // >= 640px isMd, // >= 768px isLg, // >= 1024px isXl, // >= 1280px is2Xl, // >= 1536px current, // 当前断点 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' isMobile, // < 768px isTablet, // 768px ~ 1024px isDesktop // >= 1024px } = useBreakpoints() // 示例:根据屏幕大小显示不同内容
移动端视图
平板视图
桌面视图
``` --- ### useToast 消息提示管理,统一的 Toast 通知接口。 ```ts import { useToast } from '@/composables/useToast' const { success, error, warning, info } = useToast() // 成功消息(5秒后自动消失) success('操作成功') success('数据保存成功', '提示') // 错误消息(8秒后自动消失) error('操作失败') error('保存失败,请检查网络连接', '错误') // 警告消息(8秒后自动消失) warning('该操作可能影响其他数据', '警告') // 信息消息(5秒后自动消失) info('系统将在 5 分钟后进行维护', '系统通知') ``` **接口定义:** ```ts interface UseToast { toasts: Ref success(message: string, title?: string): string error(message: string, title?: string): string warning(message: string, title?: string): string info(message: string, title?: string): string showToast(options: Omit): string removeToast(id: string): void clearAll(): void } interface Toast { id: string title?: string message?: string variant?: 'success' | 'error' | 'warning' | 'info' duration?: number } ``` --- ### useConfirm 确认对话框,用于危险操作确认。 ```ts import { useConfirm } from '@/composables/useConfirm' const { confirm, confirmDanger, confirmWarning } = useConfirm() // 普通确认 const ok = await confirm('确定要删除吗?', '确认删除') if (ok) { await deleteItem() } // 危险操作确认(红色按钮) const ok = await confirmDanger( '此操作不可撤销,确定继续吗?', '删除确认' ) // 警告确认(黄色主题) const ok = await confirmWarning( '该操作可能影响其他用户,是否继续?', '警告' ) ``` --- ### useClasses 类名工具函数,简化条件类名的生成。 ```ts import { useClasses } from '@/composables/useClasses' const { cn, conditional, fromObject } = useClasses() // 合并类名(过滤 falsy 值) const className = cn( 'base-class', isActive && 'active', error && 'error', 'another-class' ) // 结果: 'base-class active another-class' (假设 isActive=true, error=false) // 条件类名 const className = conditional(isActive, 'bg-primary', 'bg-muted') // 结果: isActive ? 'bg-primary' : 'bg-muted' // 从对象生成类名 const className = fromObject({ 'text-red-500': hasError, 'font-bold': isImportant, 'underline': isLink }) // 结果: 只包含值为 true 的键 ``` --- ## 最佳实践 ### 1. 组件开发规范 #### 使用 TypeScript ```vue ``` #### 遵循命名规范 - **组件文件**: PascalCase (如 `UserCard.vue`、`DataTable.vue`) - **Composables**: camelCase + `use` 前缀 (如 `useAuth.ts`、`useBreakpoints.ts`) - **工具函数**: camelCase (如 `formatDate.ts`、`validateEmail.ts`) - **常量**: SCREAMING_SNAKE_CASE (如 `API_BASE_URL`、`MAX_FILE_SIZE`) #### 合理使用插槽 ```vue ``` #### 统一错误处理 ```ts import { useToast } from '@/composables/useToast' import { apiClient } from '@/api/client' const { error: showError, success: showSuccess } = useToast() async function saveData() { try { await apiClient.post('/users', userData) showSuccess('用户创建成功') } catch (err: any) { const message = err.response?.data?.detail || err.message || '操作失败' showError(message, '错误') console.error('Failed to create user:', err) } } ``` --- ### 2. 样式规范 #### 优先使用 Tailwind 类 ```vue ``` #### 使用主题 CSS 变量 ```vue ``` #### 响应式设计 ```vue ``` --- ### 3. 性能优化 #### 按需导入组件 ```ts import { defineAsyncComponent } from 'vue' // 异步加载重型组件 const HeavyChart = defineAsyncComponent(() => import('./components/HeavyChart.vue') ) // 带加载状态的异步组件 const HeavyTable = defineAsyncComponent({ loader: () => import('./components/HeavyTable.vue'), loadingComponent: LoadingState, delay: 200, errorComponent: ErrorState, timeout: 3000 }) ``` #### 使用 v-memo 优化列表 ```vue ``` #### 虚拟滚动 对于超过 100 条的列表,使用虚拟滚动: ```bash npm install vue-virtual-scroller ``` ```vue ``` --- ### 4. 可访问性 (a11y) #### 语义化 HTML ```vue ``` #### 键盘导航 ```vue ``` #### ARIA 属性 ```vue ``` --- ## 组件迁移检查清单 ### 已完全迁移到 shadcn 的页面 - [x] Dashboard.vue - [x] Users.vue - [x] Settings.vue - [x] SystemSettings.vue - [x] Profile.vue - [x] ActivityLogs.vue - [x] Announcements.vue - [x] ApiKeys.vue - [x] AuditLogs.vue - [x] MyApiKeys.vue - [x] Usage.vue - [x] ProviderList.vue - [x] MyProviders.vue - [x] CacheMonitoring.vue - [x] ProviderDetailNew.vue ### 部分迁移或自定义样式 - [ ] Home.vue - 使用大量自定义动画和样式(不建议迁移) --- ## 更新日志 ### v2.3.0 (2025-11-18) **新增组件:** - `ConfirmButton` - 带确认对话框的按钮组件 - `ActionMenu` - 操作菜单下拉组件 **优化导入系统:** - 创建 `@/components/ui/index.ts` 统一导出所有 shadcn UI 组件 - 完善 `@/components/layout/index.ts` 和 `@/components/common/index.ts` - 支持更简洁的组件导入方式 **导入方式优化:** ```ts // 旧版导入 (繁琐) import Button from '@/components/ui/button.vue' import Input from '@/components/ui/input.vue' import Card from '@/components/ui/card.vue' // 新版导入 (推荐) import { Button, Input, Card } from '@/components/ui' import { PageHeader, Section, CardSection } from '@/components/layout' import { DataTable, ConfirmButton, ActionMenu } from '@/components/common' ``` **文档:** - 添加 `ConfirmButton` 和 `ActionMenu` 组件完整文档 - 更新组件导入最佳实践 ### v2.2.0 (2025-11-18) **重构:** - 统一布局组件目录: 将 `layout-v2` 合并到 `layout` - 所有布局组件现在从 `@/components/layout` 统一导入 - 删除冗余的 `layout-v2` 目录 **文档:** - 添加完整的布局组件文档和使用示例 - 标记 `ShellHeader` 为待废弃组件 **迁移指南:** ```ts // 旧版导入 (已废弃) import { PageHeader } from '@/components/layout-v2' // 新版导入 (推荐) import { PageHeader } from '@/components/layout' ``` ### v2.1.0 (2025-11-18) **新增:** - 完善所有组件文档和使用示例 - 添加完整的 TypeScript 类型定义 - 统一 Toast 工具函数接口(useToast) - 完善响应式支持(useBreakpoints) **修复:** - 修复 CacheMonitoring.vue 的 toast 调用 - 统一所有页面的组件使用 **文档:** - 更新所有组件的使用示例 - 添加最佳实践章节 - 添加性能优化指南 - 添加可访问性指南 ### v2.0.0 (2025-11-17) - 基础设计系统搭建 - 实现所有核心业务组件 - 建立主题系统 --- ## 参考资源 - [shadcn/ui 官方文档](https://ui.shadcn.com/) - [Tailwind CSS 文档](https://tailwindcss.com/docs) - [Vue 3 文档](https://vuejs.org/) - [Lucide Icons](https://lucide.dev/) - [WCAG 2.1 标准](https://www.w3.org/WAI/WCAG21/quickref/) - [主题配置文件](src/config/theme.ts)