# OOP + Composition API 组合使用方案 **日期**: 2026-01-31 **核心理念**: 取长补短,渐进式迁移 --- ## 🎯 设计原则 ### OOP 负责什么 - ✅ **核心业务逻辑**(复杂的状态管理) - ✅ **需要严格初始化顺序的功能**(如 ZIP 浏览) - ✅ **可复用的服务**(文件操作、预览等) - ✅ **需要依赖注入和测试的模块** ### Composition API 负责什么 - ✅ **Vue 组件的响应式状态** - ✅ **简单的 UI 逻辑** - ✅ **生命周期钩子** - ✅ **DOM 事件处理** ### 分层架构 ``` ┌─────────────────────────────────────┐ │ Vue 组件层 (Composition) │ ← UI 交互、生命周期 │ index.vue | 组件 ``` --- ## 🔄 渐进式迁移策略 ### 阶段 1:新功能使用组合方案(立即开始) ```typescript // ✅ 新功能:使用 OOP 服务 const newFeature = useNewFeature({ service: new NewFeatureService() }) ``` ### 阶段 2:问题模块优先迁移(本周) ```typescript // ❌ 旧代码(有问题) const zipBrowser = useZipBrowser({ ... }) // ✅ 新代码(使用服务) const zipBrowser = useZipBrowser({ fileApi, previewService, // 依赖注入 fileList, filePath }) ``` **优先迁移:** 1. `useZipBrowser` - 初始化顺序问题最多 2. `useFilePreview` - 返回值过多 3. `useFileEdit` - 状态管理复杂 ### 阶段 3:其他功能逐步迁移(1-2周) ```typescript // 老代码保持不变,新代码用新方案 const oldFeature = useOldFeature() // 保持原样 const newFeature = useNewFeature({ // 新方案 service: new NewFeatureService() }) ``` ### 阶段 4:完全迁移后(1个月后) ```typescript // 全部使用组合方案 const { fileSystem, preview, zip, edit } = useServices({ services: { fileSystem: new FileSystemService(), preview: new FilePreviewService(), zip: new ZipBrowserService() } }) ``` --- ## 💡 使用场景对比 ### 场景 1:简单 UI 逻辑(用 Composition API) ```typescript // ✅ 简单的响应式状态 const showDialog = ref(false) const dialogMessage = ref('') const openDialog = (msg: string) => { dialogMessage.value = msg showDialog.value = true } ``` ### 场景 2:复杂业务逻辑(用 OOP 服务) ```typescript // ✅ 复杂的状态管理 class ZipBrowserService { constructor( private preview: FilePreviewService, // 依赖注入 private fileApi: FileApiService ) {} async enterZipMode(path: string) { // 复杂的初始化逻辑 await this.preview.cleanup() this._isBrowsingZip.value = true await this.loadZipContents() } } ``` ### 场景 3:需要组合两者(组合使用) ```typescript // 服务层(OOP)- 核心逻辑 class FilePreviewService { async previewImage(path: string) { const url = await this.fileApi.getImageUrl(path) this._previewUrl.value = url } } // Composable - 桥接到 Vue function useFilePreview() { const service = new FilePreviewService(...) return { // 响应式状态(Composition API) previewUrl: service.previewUrl, // 方法(委托给服务) previewImage: (path: string) => service.previewImage(path), // 服务实例(可选) $service: service } } // 组件 - 使用 const { previewUrl, previewImage } = useFilePreview() ``` --- ## 🎓 最佳实践 ### 1. 服务类设计原则 ```typescript class GoodService { // ✅ 状态用 ref private readonly _state = ref(initialState) // ✅ 构造函数注入依赖 constructor( private readonly dependency: OtherService ) {} // ✅ 提供访问器 get state(): Ref { return this._state } // ✅ 方法返回值(不返回 ref) doSomething(): void { this._state.value = { ... } } } ``` ### 2. Composable 设计原则 ```typescript function useGoodService(options: Options) { // ✅ 创建服务实例 const service = new GoodService(options.dependency) return { // ✅ 返回 ref(响应式) state: service.state, // ✅ 绑定方法 doSomething: () => service.doSomething(), // ✅ 可选:暴露服务 $service: service } } ``` ### 3. 组件使用原则 ```typescript // ✅ 简单场景:只用返回值 const { state, doSomething } = useGoodService() // ✅ 复杂场景:访问服务实例 const { $service } = useGoodService() $service.advancedMethod() // ✅ 生命周期钩子(Composition API) onMounted(() => { $service.initialize() }) ``` --- ## 📊 对比总结 | 维度 | OOP 服务 | Composable | 组件使用 | |-----|---------|-----------|---------| | **适用场景** | 复杂逻辑、初始化顺序 | 简单逻辑、UI 状态 | 组合使用 | | **状态管理** | ref 私有字段 | ref 变量 | ref 变量 | | **依赖注入** | 构造函数 | 函数参数 | 函数参数 | | **测试性** | ✅ 容易 | ⚠️ 中等 | ⚠️ 中等 | | **Vue 兼容** | ⚠️ 需要适配 | ✅ 完美 | ✅ 完美 | | **初始化保证** | ✅ 构造函数 | ❌ 手动保证 | - | --- ## 🚀 快速开始模板 ### 创建服务类 ```bash # 1. 创建服务文件 services/MyFeatureService.ts # 2. 创建 composable 适配器 composables/useMyFeature.ts # 3. 在组件中使用 components/MyComponent.vue ``` ### 模板代码 ```typescript // 1. 服务类 export class MyFeatureService { constructor(private dep: DependencyService) {} get state() { return this._state } doSomething() { ... } } // 2. Composable export function useMyFeature() { const service = new MyFeatureService(dep) return { state: service.state, doSomething: () => service.doSomething(), $service: service } } // 3. 组件 const { state, doSomething } = useMyFeature() ``` --- ## ✅ 总结 ### 组合方案的优势 1. **✅ 解决初始化问题** - OOP 构造函数保证顺序 2. **✅ 保持开发体验** - Composition API 风格 3. **✅ 渐进式迁移** - 不需要大规模重构 4. **✅ 高内聚低耦合** - 服务封装,适配器桥接 5. **✅ 易于测试** - 服务层独立测试 ### 核心理念 > **OOP 负责复杂逻辑,Composition 负责 UI 交互** --- **生成时间**: 2026-01-31 **下一步**: 创建第一个 OOP 服务示例(ZipBrowserService)?