# 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)?