# 组件开发规范

<cite>
**本文引用的文件**
- [AudioDownload.vue](file://my-uniapp-vue3/src/components/AudioDownload.vue)
- [MiniPlayer.vue](file://my-uniapp-vue3/src/components/MiniPlayer.vue)
- [LazyImage.vue](file://my-uniapp-vue3/src/components/LazyImage.vue)
- [Skeleton.vue](file://my-uniapp-vue3/src/components/Skeleton.vue)
- [SkeletonList.vue](file://my-uniapp-vue3/src/components/SkeletonList.vue)
- [audio.ts](file://my-uniapp-vue3/src/store/audio.ts)
- [user.ts](file://my-uniapp-vue3/src/store/user.ts)
- [index.vue](file://my-uniapp-vue3/src/pages/player/index.vue)
- [index.vue](file://my-uniapp-vue3/src/pages/index/index.vue)
- [index.ts](file://my-uniapp-vue3/src/types/index.ts)
- [request.ts](file://my-uniapp-vue3/src/utils/request.ts)
- [storage.ts](file://my-uniapp-vue3/src/utils/storage.ts)
- [package.json](file://my-uniapp-vue3/package.json)
- [tsconfig.json](file://my-uniapp-vue3/tsconfig.json)
- [vite.config.ts](file://my-uniapp-vue3/vite.config.ts)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [组件详解与最佳实践](#组件详解与最佳实践)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本规范面向AI有声书生成平台的前端组件开发，目标是统一组件命名、文件组织、代码风格与类型约束，明确属性定义、事件声明与插槽设计，规范状态管理与数据流，提供测试、调试与性能优化策略，并覆盖跨平台兼容、响应式设计与无障碍访问要点，最后给出版本管理、文档与发布流程的标准。

## 项目结构
前端采用基于Vue 3 + TypeScript + Pinia + UniApp的多端一体化架构，组件集中在src/components目录，页面位于src/pages，全局状态位于src/store，类型定义位于src/types，工具函数位于src/utils，构建与运行配置位于根目录配置文件。

```mermaid
graph TB
subgraph "页面层"
P_Index["pages/index/index.vue"]
P_Player["pages/player/index.vue"]
end
subgraph "组件层"
C_AudioDownload["components/AudioDownload.vue"]
C_LazyImage["components/LazyImage.vue"]
C_Skeleton["components/Skeleton.vue"]
C_SkeletonList["components/SkeletonList.vue"]
C_MiniPlayer["components/MiniPlayer.vue"]
end
subgraph "状态管理层"
S_Audio["store/audio.ts"]
S_User["store/user.ts"]
end
subgraph "工具与类型"
U_Request["utils/request.ts"]
U_Storage["utils/storage.ts"]
T_Index["types/index.ts"]
end
subgraph "构建与配置"
CFG_Pkg["package.json"]
CFG_TS["tsconfig.json"]
CFG_Vite["vite.config.ts"]
end
P_Index --> C_MiniPlayer
P_Player --> C_AudioDownload
P_Player --> S_Audio
P_Index --> S_User
C_AudioDownload --> U_Request
C_LazyImage --> U_Request
S_Audio --> U_Request
S_User --> U_Request
S_Audio --> T_Index
S_User --> T_Index
CFG_Pkg --> CFG_TS
CFG_Pkg --> CFG_Vite
```

图示来源
- [index.vue:106-108](file://my-uniapp-vue3/src/pages/index/index.vue#L106-L108)
- [index.vue:84-92](file://my-uniapp-vue3/src/pages/player/index.vue#L84-L92)
- [audio.ts:1-297](file://my-uniapp-vue3/src/store/audio.ts#L1-297)
- [user.ts:1-107](file://my-uniapp-vue3/src/store/user.ts#L1-107)
- [request.ts:1-207](file://my-uniapp-vue3/src/utils/request.ts#L1-207)
- [storage.ts:1-63](file://my-uniapp-vue3/src/utils/storage.ts#L1-63)
- [index.ts:1-89](file://my-uniapp-vue3/src/types/index.ts#L1-89)
- [package.json:1-65](file://my-uniapp-vue3/package.json#L1-65)
- [tsconfig.json:1-14](file://my-uniapp-vue3/tsconfig.json#L1-14)
- [vite.config.ts:1-24](file://my-uniapp-vue3/vite.config.ts#L1-24)

章节来源
- [package.json:1-65](file://my-uniapp-vue3/package.json#L1-65)
- [tsconfig.json:1-14](file://my-uniapp-vue3/tsconfig.json#L1-14)
- [vite.config.ts:1-24](file://my-uniapp-vue3/vite.config.ts#L1-24)

## 核心组件
- 音频下载组件：支持带重试的下载、进度展示与本地保存，具备插槽扩展能力。
- 迷你播放器：全局悬浮播放器，条件渲染与播放控制，与Pinia状态联动。
- 懒加载图片：基于uni-app的懒加载策略，支持占位图与事件透传。
- 骨架屏：单元素骨架屏与列表骨架屏，支持多种布局与动画。
- 页面组件：播放页与首页，演示组件组合、状态管理与数据流。

章节来源
- [AudioDownload.vue:1-179](file://my-uniapp-vue3/src/components/AudioDownload.vue#L1-L179)
- [MiniPlayer.vue:1-166](file://my-uniapp-vue3/src/components/MiniPlayer.vue#L1-L166)
- [LazyImage.vue:1-73](file://my-uniapp-vue3/src/components/LazyImage.vue#L1-L73)
- [Skeleton.vue:1-72](file://my-uniapp-vue3/src/components/Skeleton.vue#L1-L72)
- [SkeletonList.vue:1-283](file://my-uniapp-vue3/src/components/SkeletonList.vue#L1-L283)
- [index.vue:1-190](file://my-uniapp-vue3/src/pages/player/index.vue#L1-L190)
- [index.vue:1-200](file://my-uniapp-vue3/src/pages/index/index.vue#L1-L200)

## 架构总览
组件开发遵循“页面-组件-状态-工具-类型”的分层，页面负责编排与交互，组件负责UI与行为，Pinia集中管理音频与用户状态，工具模块封装请求与存储，类型模块提供强类型约束。

```mermaid
sequenceDiagram
participant Page as "页面组件"
participant Comp as "业务组件"
participant Store as "Pinia状态"
participant Util as "工具模块"
participant API as "后端接口"
Page->>Comp : 传递属性/触发事件
Comp->>Util : 调用请求/存储工具
Util->>API : 发起HTTP请求
API-->>Util : 返回数据
Util-->>Comp : 标准化结果
Comp->>Store : 更新状态
Store-->>Page : 计算属性/状态变更
```

图示来源
- [index.vue:192-384](file://my-uniapp-vue3/src/pages/player/index.vue#L192-L384)
- [audio.ts:88-141](file://my-uniapp-vue3/src/store/audio.ts#L88-L141)
- [request.ts:34-99](file://my-uniapp-vue3/src/utils/request.ts#L34-L99)

## 组件详解与最佳实践

### 命名约定与文件组织
- 组件文件：PascalCase.vue，如 AudioDownload.vue、MiniPlayer.vue。
- 组件导出：默认导出Vue组件，内部使用<script setup>与TypeScript。
- 文件夹组织：按功能域分层，components、pages、store、utils、types。
- 类型文件：统一在types/index.ts中声明，避免重复定义。

章节来源
- [AudioDownload.vue:1-179](file://my-uniapp-vue3/src/components/AudioDownload.vue#L1-L179)
- [MiniPlayer.vue:1-166](file://my-uniapp-vue3/src/components/MiniPlayer.vue#L1-L166)
- [LazyImage.vue:1-73](file://my-uniapp-vue3/src/components/LazyImage.vue#L1-L73)
- [Skeleton.vue:1-72](file://my-uniapp-vue3/src/components/Skeleton.vue#L1-L72)
- [SkeletonList.vue:1-283](file://my-uniapp-vue3/src/components/SkeletonList.vue#L1-L283)
- [index.ts:1-89](file://my-uniapp-vue3/src/types/index.ts#L1-89)

### 属性定义与事件声明
- 属性：使用withDefaults(defineProps<>()进行类型约束与默认值声明，避免可选属性的空值判断。
- 事件：使用defineEmits<>声明事件签名，确保事件回调参数类型安全。
- 插槽：默认插槽与具名插槽结合，允许父组件自定义样式与交互。

示例参考
- AudioDownload.vue：属性含url、filename、audioId；事件未显式声明emit，建议补充以提升类型安全。
- LazyImage.vue：属性含src、mode、placeholder、lazyLoad；显式声明load/error/click事件。
- MiniPlayer.vue：无props，通过计算属性与全局状态控制渲染。

章节来源
- [AudioDownload.vue:18-32](file://my-uniapp-vue3/src/components/AudioDownload.vue#L18-L32)
- [LazyImage.vue:15-32](file://my-uniapp-vue3/src/components/LazyImage.vue#L15-L32)
- [MiniPlayer.vue:33-46](file://my-uniapp-vue3/src/components/MiniPlayer.vue#L33-L46)

### 数据流与状态管理
- Pinia Store：集中管理音频播放、播放列表、播放模式、播放速率等；提供计算属性与副作用监听。
- 页面与组件：通过store暴露的方法与计算属性读取状态，避免直接修改store内部状态。
- 生命周期：在页面onShow/onMounted中同步store状态，确保UI与状态一致。

```mermaid
flowchart TD
Start(["页面进入"]) --> LoadState["读取store状态<br/>computed/isPlaying/currentTime/duration"]
LoadState --> RenderUI["渲染UI与组件"]
RenderUI --> UserAction{"用户交互？"}
UserAction --> |播放/暂停| Toggle["togglePlay()"]
UserAction --> |切换歌曲| NextPrev["playNext()/playPrev()"]
UserAction --> |设置速率| SetRate["setPlayRate()"]
Toggle --> UpdateStore["store内部更新状态"]
NextPrev --> UpdateStore
SetRate --> UpdateStore
UpdateStore --> EmitEvent["audioContext事件回调<br/>onPlay/onPause/onEnded/onTimeUpdate"]
EmitEvent --> UpdateStore
UpdateStore --> RenderUI
```

图示来源
- [audio.ts:29-79](file://my-uniapp-vue3/src/store/audio.ts#L29-L79)
- [audio.ts:157-180](file://my-uniapp-vue3/src/store/audio.ts#L157-L180)
- [audio.ts:241-247](file://my-uniapp-vue3/src/store/audio.ts#L241-L247)
- [index.vue:299-307](file://my-uniapp-vue3/src/pages/player/index.vue#L299-L307)

章节来源
- [audio.ts:1-297](file://my-uniapp-vue3/src/store/audio.ts#L1-L297)
- [index.vue:192-384](file://my-uniapp-vue3/src/pages/player/index.vue#L192-L384)

### TypeScript类型定义与约束
- 类型集中：在types/index.ts中定义UserInfo、AudioItem、Voice、VoiceParams、MemberStatus、ApiResponse、PaginationResult等。
- 接口字段：严格区分后端返回字段与前端使用字段，如_audioId、_id、audioId等。
- 泛型与工具：对请求工具函数使用泛型约束返回值，保证调用方类型安全。

章节来源
- [index.ts:9-89](file://my-uniapp-vue3/src/types/index.ts#L9-L89)
- [request.ts:34-99](file://my-uniapp-vue3/src/utils/request.ts#L34-L99)

### 组件复用策略
- 组合优先：将通用逻辑下沉至store与工具模块，组件仅关注UI与交互。
- 插槽扩展：通过具名/默认插槽允许父组件定制外观与行为。
- 条件渲染：根据路由、权限、状态动态决定组件可见性与内容。

章节来源
- [MiniPlayer.vue:33-46](file://my-uniapp-vue3/src/components/MiniPlayer.vue#L33-L46)
- [index.vue:106-108](file://my-uniapp-vue3/src/pages/index/index.vue#L106-L108)

### 跨平台兼容与响应式设计
- 平台差异：使用条件编译宏区分APP与H5环境，避免平台特定API的直接耦合。
- 响应式单位：广泛使用rpx适配移动端屏幕密度，避免px导致的缩放问题。
- 导航与路由：使用uni.navigateTo/uni.navigateBack等跨平台API。

章节来源
- [index.vue:312-317](file://my-uniapp-vue3/src/pages/player/index.vue#L312-L317)
- [index.vue:613-629](file://my-uniapp-vue3/src/pages/player/index.vue#L613-L629)

### 无障碍访问
- 文案与图标：提供可读文本与语义化图标，避免仅依赖视觉提示。
- 交互反馈：使用uni.showToast/uni.showModal提供明确的错误与成功提示。
- 键盘与焦点：在可交互元素上提供清晰的视觉反馈与状态指示。

章节来源
- [AudioDownload.vue:43-63](file://my-uniapp-vue3/src/components/AudioDownload.vue#L43-L63)
- [request.ts:135-159](file://my-uniapp-vue3/src/utils/request.ts#L135-L159)

### 测试方法与调试技巧
- 单元测试：对纯函数与工具模块进行单元测试，如请求封装、存储工具。
- 集成测试：在页面组件中模拟store状态，验证组件渲染与交互。
- 调试：利用vconsole、日志输出与断点定位问题；对API请求进行拦截与观察。

章节来源
- [request.ts:112-167](file://my-uniapp-vue3/src/utils/request.ts#L112-L167)

### 性能优化策略
- 懒加载：图片组件支持懒加载与占位图，减少首屏压力。
- 骨架屏：在数据加载期间使用骨架屏提升感知性能。
- 缓存：请求层支持GET请求缓存与TTL控制，降低重复请求。
- 状态更新：避免不必要的响应式更新，使用computed与局部状态分离。

章节来源
- [LazyImage.vue:38-46](file://my-uniapp-vue3/src/components/LazyImage.vue#L38-L46)
- [Skeleton.vue:1-72](file://my-uniapp-vue3/src/components/Skeleton.vue#L1-L72)
- [request.ts:20-55](file://my-uniapp-vue3/src/utils/request.ts#L20-L55)

## 依赖关系分析

```mermaid
graph LR
A["AudioDownload.vue"] --> R["request.ts"]
M["MiniPlayer.vue"] --> S1["store/audio.ts"]
L["LazyImage.vue"] --> R
S["Skeleton.vue"] --> S
SL["SkeletonList.vue"] --> SL
P1["pages/index/index.vue"] --> M
P2["pages/player/index.vue"] --> A
P2 --> S1
S1 --> R
S1 --> T["types/index.ts"]
S2["store/user.ts"] --> R
S2 --> T
```

图示来源
- [AudioDownload.vue:1-179](file://my-uniapp-vue3/src/components/AudioDownload.vue#L1-L179)
- [MiniPlayer.vue:1-166](file://my-uniapp-vue3/src/components/MiniPlayer.vue#L1-L166)
- [LazyImage.vue:1-73](file://my-uniapp-vue3/src/components/LazyImage.vue#L1-L73)
- [Skeleton.vue:1-72](file://my-uniapp-vue3/src/components/Skeleton.vue#L1-L72)
- [SkeletonList.vue:1-283](file://my-uniapp-vue3/src/components/SkeletonList.vue#L1-L283)
- [index.vue:106-108](file://my-uniapp-vue3/src/pages/index/index.vue#L106-L108)
- [index.vue:84-92](file://my-uniapp-vue3/src/pages/player/index.vue#L84-L92)
- [audio.ts:1-297](file://my-uniapp-vue3/src/store/audio.ts#L1-L297)
- [user.ts:1-107](file://my-uniapp-vue3/src/store/user.ts#L1-107)
- [request.ts:1-207](file://my-uniapp-vue3/src/utils/request.ts#L1-207)
- [index.ts:1-89](file://my-uniapp-vue3/src/types/index.ts#L1-89)

## 性能考量
- 组件渲染：避免在模板中进行复杂计算，将计算逻辑移至computed或store。
- 网络请求：对高频请求启用缓存与节流，减少无效请求。
- 资源加载：图片懒加载与骨架屏配合，改善用户体验。
- 状态粒度：拆分store模块，避免单一store过大导致的全量响应式更新。

## 故障排查指南
- 下载失败：检查网络状态与重试逻辑，确认uni.downloadFile回调与错误处理。
- 播放异常：检查audioContext初始化、src变更与readyState，关注onError回调。
- 请求失败：查看请求封装的日志输出与错误分支，区分401、429、5xx等场景。
- 存储异常：区分H5与小程序环境的存储API差异，确保序列化与反序列化正确。

章节来源
- [AudioDownload.vue:48-129](file://my-uniapp-vue3/src/components/AudioDownload.vue#L48-L129)
- [audio.ts:29-79](file://my-uniapp-vue3/src/store/audio.ts#L29-L79)
- [request.ts:135-167](file://my-uniapp-vue3/src/utils/request.ts#L135-L167)
- [storage.ts:1-63](file://my-uniapp-vue3/src/utils/storage.ts#L1-L63)

## 结论
通过统一的命名与文件组织、严格的TypeScript类型约束、清晰的数据流与状态管理、完善的插槽与事件设计，以及跨平台兼容与性能优化策略，可以显著提升组件的可维护性与可复用性。建议在团队内推广此规范，并持续完善测试与文档体系。

## 附录

### 版本管理与发布流程
- 版本号：遵循语义化版本，变更类型包括feat、fix、docs、refactor、perf等。
- 提交规范：使用约定式提交，便于自动生成变更日志。
- 构建脚本：多端构建脚本在package.json中定义，确保各平台一致性。
- 代理配置：Vite代理指向本地或线上服务，便于联调。

章节来源
- [package.json:4-37](file://my-uniapp-vue3/package.json#L4-L37)
- [vite.config.ts:7-22](file://my-uniapp-vue3/vite.config.ts#L7-L22)