# 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 runApp(appId: string): Promise } ``` ### 5.2 状态管理接口 #### 5.2.1 桌面状态接口 ```typescript interface DesktopStore { // 状态 appIcons: Ref gridTemplate: Ref systemStatus: Ref showSystemStatus: Ref // Getters gridStyle: ComputedRef // 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('systemService') // 建议添加类型安全检查 const systemService = inject('systemService') if (!systemService) { throw new Error('系统服务未正确注入') } ``` ## 7. 测试策略 ### 7.1 UI组件测试 - 展示组件:测试不同props输入下的渲染结果 - 容器组件:测试与状态管理和服务的交互 ### 7.2 状态管理测试 - 测试状态更新的正确性 - 测试响应式数据的自动更新 ### 7.3 集成测试 - 测试完整的数据流和用户操作流程 - 验证UI与核心服务的交互正确性 ### 7.4 现有测试策略优化 项目已具备基本的测试框架,建议: 1. 增加对展示组件的单元测试 2. 完善容器组件与服务的集成测试 3. 建立端到端测试覆盖核心用户场景