This commit is contained in:
2025-09-28 14:32:00 +08:00
parent 7b1dff9ea1
commit f1ba609254

View File

@@ -0,0 +1,370 @@
# UI模块化设计方案
## 1. 概述
本方案旨在将当前项目中的UI组件与核心业务逻辑进行彻底分离实现UI层只负责数据渲染核心层专注于数据处理的架构模式。通过模块化重构提高代码的可维护性、可测试性和可扩展性。
### 1.1 设计目标
- 实现UI层与核心业务逻辑的完全解耦
- UI组件只负责接收数据并渲染不包含任何业务逻辑
- 核心服务层提供统一的数据接口和状态管理
- 通过响应式数据绑定实现UI与数据的自动同步
### 1.2 核心原则
- **数据驱动**: UI组件通过props接收数据通过事件触发操作
- **单一职责**: UI组件只负责渲染核心服务只负责数据处理
- **响应式更新**: 数据变化自动触发UI更新
- **模块化设计**: 各模块职责清晰,依赖关系明确
### 1.3 项目现状分析
当前项目已经具备良好的分层架构:
- 使用Pinia进行状态管理
- 通过依赖注入提供系统服务
- UI组件与核心服务之间通过明确定义的接口交互
- 采用Vue 3 Composition API实现逻辑复用
## 2. 架构设计
### 2.1 整体架构图
```mermaid
graph TD
A[UI层] --> B[状态管理层]
B --> C[核心服务层]
C --> D[数据源]
C --> E[外部API]
B --> A
subgraph UI层
A
end
subgraph 核心层
B
C
D
E
end
```
### 2.2 现有架构分析
项目当前已具备良好的分层架构,但存在部分逻辑混合的情况:
1. **UI层**包含Vue组件和部分业务逻辑
2. **状态管理层**使用Pinia管理全局状态
3. **核心服务层**SystemServiceIntegration统一管理系统服务
4. **依赖注入**通过Vue的provide/inject机制传递系统服务
### 2.3 模块划分优化
| 模块 | 职责 | 包含内容 |
| ------------ | ---------------------- | ------------------------------ |
| UI组件模块 | 负责界面展示和用户交互 | 所有Vue组件、样式文件 |
| 状态管理模块 | 管理应用状态和数据流 | Pinia stores、响应式数据 |
| 核心服务模块 | 处理业务逻辑和数据操作 | 系统服务、应用管理、窗体管理等 |
| 工具模块 | 提供通用工具函数 | 工具函数、类型定义 |
## 3. UI模块重构方案
### 3.1 当前结构分析
当前项目UI相关代码分散在以下目录中
- `src/ui/`: 主要UI组件
- `src/apps/`: 内置应用组件
- `src/common/`: 通用UI工具和组件
### 3.2 重构后的UI模块结构
```
src/
├── ui/
│ ├── components/ # 通用UI组件
│ ├── containers/ # 容器组件
│ ├── views/ # 页面视图组件
│ ├── composables/ # UI专用组合式函数
│ ├── styles/ # 样式文件
│ └── types/ # UI相关类型定义
├── core/ # 核心业务逻辑从UI中抽离
├── stores/ # 状态管理
└── services/ # 核心服务层
```
### 3.3 UI组件分类
#### 3.3.1 展示组件Pure Components
展示组件只负责接收数据并渲染,不包含任何业务逻辑:
| 组件名称 | 职责 | 输入数据 | 输出事件 |
| ----------- | ------------ | ---------------------- | ------------------------------- |
| AppIcon | 应用图标展示 | iconInfo, gridTemplate | dragStart, dragEnd, doubleClick |
| AppRenderer | 应用渲染器 | appId, windowId | loaded, error |
#### 3.3.2 容器组件Container Components
容器组件负责连接展示组件与状态管理:
| 组件名称 | 职责 | 连接状态 | 业务逻辑 |
| ---------------- | ---------- | ----------------------- | ------------------ |
| DesktopContainer | 桌面容器 | appIcons, systemStatus | 应用启动、状态更新 |
| WindowManager | 窗口管理器 | windows | 窗口创建、销毁 |
| AppRenderer | 应用渲染器 | appComponent, iframeUrl | 应用加载、错误处理 |
## 4. 数据流设计
### 4.1 数据流向图
```mermaid
graph LR
A[核心服务] --> B[状态管理]
B --> C[UI组件]
C --> D[用户操作]
D --> E[事件处理]
E --> A
style A fill:#cde4ff
style B fill:#ffd7c1
style C fill:#d3f8d3
style D fill:#fff2c1
style E fill:#e6d7ff
```
### 4.2 状态管理设计
项目已使用Pinia进行状态管理建议继续沿用并扩展
#### 4.2.1 桌面状态
```typescript
interface DesktopState {
appIcons: IDesktopAppIcon[]
gridTemplate: IGridTemplateParams
systemStatus: SystemStatus
showSystemStatus: boolean
}
```
#### 4.2.2 窗口状态
```typescript
interface WindowState {
windows: BuiltInWindow[]
activeWindowId: string | null
}
```
### 4.3 数据获取与更新流程
```mermaid
sequenceDiagram
participant U as UI组件
participant S as 状态管理
participant C as 核心服务
U->>S: 读取状态数据
S-->>U: 返回响应式数据
U->>U: 渲染界面
U->>C: 触发用户操作
C->>S: 更新状态
S->>U: 自动更新界面
```
### 4.4 依赖注入机制
项目通过Vue的provide/inject机制实现服务注入
1. 在main.ts中创建并提供SystemServiceIntegration实例
2. UI组件通过inject获取系统服务
3. 系统服务提供统一的API访问核心功能
## 5. 接口设计
### 5.1 UI组件接口规范
#### 5.1.1 展示组件接口
```typescript
// AppIcon组件接口
interface AppIconProps {
iconInfo: IDesktopAppIcon
gridTemplate: IGridTemplateParams
}
interface AppIconEvents {
(e: 'dragStart', event: DragEvent): void
(e: 'dragEnd', event: DragEvent): void
(e: 'doubleClick'): void
}
// AppRenderer组件接口
interface AppRendererProps {
appId: string
windowId?: string
}
interface AppRendererEvents {
(e: 'loaded'): void
(e: 'error', error: Error): void
}
```
#### 5.1.2 容器组件接口
```typescript
// DesktopContainer组件接口
interface DesktopContainerProps {
// 无需props直接从状态管理获取数据
}
interface DesktopContainerMethods {
refreshApps(): Promise<void>
runApp(appId: string): Promise<void>
}
```
### 5.2 状态管理接口
#### 5.2.1 桌面状态接口
```typescript
interface DesktopStore {
// 状态
appIcons: Ref<IDesktopAppIcon[]>
gridTemplate: Ref<IGridTemplateParams>
systemStatus: Ref<SystemStatus>
showSystemStatus: Ref<boolean>
// Getters
gridStyle: ComputedRef<GridStyle>
// Actions
updateAppIcons(icons: IDesktopAppIcon[]): void
updateSystemStatus(status: SystemStatus): void
toggleSystemStatus(show: boolean): void
saveIconPositions(): void
}
```
## 6. 实现方案
### 6.1 UI模块独立化步骤
1. **创建独立的UI模块目录结构**
- 将现有的UI组件按功能重新组织
- 分离展示组件和容器组件
2. **抽离业务逻辑到核心服务**
- 将应用启动逻辑移至SystemServiceIntegration
- 将状态管理移至Pinia stores
3. **重构组件数据流**
- 使用props传递数据
- 使用emit触发事件
- 通过状态管理实现响应式更新
### 6.2 现有组件优化
1. **DesktopContainer组件**
- 保持现有的inject机制获取系统服务
- 将应用启动逻辑完全委托给系统服务
- 通过响应式数据驱动UI更新
2. **AppIcon组件**
- 保持纯展示组件特性
- 通过事件与父组件通信
3. **WindowManager组件**
- 保持现有的窗口管理逻辑
- 通过inject获取系统服务
4. **AppRenderer组件**
- 负责应用渲染逻辑
- 支持内置应用和外部应用渲染
- 内置应用使用Vue组件直接渲染
- 外部应用使用iframe加载渲染
### 6.3 核心改造点
#### 6.3.1 DesktopContainer组件改造
当前的DesktopContainer组件包含了太多业务逻辑需要进行以下优化
1. **保持组件结构**:无需拆分为多个组件,但需明确职责划分
2. **业务逻辑委托**:将应用启动等业务逻辑完全委托给系统服务
3. **状态管理优化**通过响应式数据驱动UI更新
#### 6.3.2 应用启动流程优化
```mermaid
graph TD
A[用户双击图标] --> B[DesktopContainer组件]
B --> C[调用系统服务]
C --> D[SystemServiceIntegration]
D --> E[ApplicationLifecycleManager]
E --> F[创建应用实例]
```
#### 6.3.3 子应用加载机制
项目需要支持两种类型的应用加载:
1. **内置应用加载**
- 直接使用Vue 3组件加载机制
- 通过AppRegistry获取应用组件
- 无需异步加载,立即渲染
2. **外部应用加载**
- 使用iframe沙箱环境加载
- 通过ExternalAppDiscovery发现应用
- 异步加载应用资源
- 外部加载逻辑可暂时留空,后期实现
### 6.4 依赖注入优化
项目已通过Vue的provide/inject机制实现服务注入建议保持现有模式并进行优化
```typescript
// main.ts - 保持现有实现
app.provide('systemService', systemService)
// UI组件中使用 - 保持现有实现
const systemService = inject<SystemServiceIntegration>('systemService')
// 建议添加类型安全检查
const systemService = inject<SystemServiceIntegration>('systemService')
if (!systemService) {
throw new Error('系统服务未正确注入')
}
```
## 7. 测试策略
### 7.1 UI组件测试
- 展示组件测试不同props输入下的渲染结果
- 容器组件:测试与状态管理和服务的交互
### 7.2 状态管理测试
- 测试状态更新的正确性
- 测试响应式数据的自动更新
### 7.3 集成测试
- 测试完整的数据流和用户操作流程
- 验证UI与核心服务的交互正确性
### 7.4 现有测试策略优化
项目已具备基本的测试框架,建议:
1. 增加对展示组件的单元测试
2. 完善容器组件与服务的集成测试
3. 建立端到端测试覆盖核心用户场景