Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions docs/refactor-homeview-composables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# HomeView.vue Composables 重构总结

## 重构目标

将 HomeView.vue 从单一巨型组件(2745 行)拆分为多个可维护的 composables,提高代码可读性、可测试性和可复用性。

## 重构成果

### 总体指标

| 指标 | 重构前 | 重构后 | 变化 |
|------|--------|--------|------|
| HomeView.vue 行数 | 2745 | 2154 | **-591 行 (-21.5%)** |
| Composables 数量 | 0 | 7 | +7 |
| Composables 总行数 | 0 | 935 | +935 |
| 总代码行数 | 2745 | 3089 | +344 |

**注:** 总代码行数增加是因为增加了接口定义、JSDoc 注释和更清晰的结构,这些都提高了代码质量。

### 提取的 Composables

#### 阶段1: 基础数据处理(3个 composables,-230 行)

1. **useDisplayPathCache** (66 行)
- 功能:路径显示缓存管理
- 优化:移除 Windows 冗余前缀,加速路径显示
- 文件:`src/views/HomeView/composables/useDisplayPathCache.ts`

2. **useProjectSearch** (98 行)
- 功能:基于 Fuse.js 的模糊搜索
- 特性:防抖、索引缓存、增量更新
- 文件:`src/views/HomeView/composables/useProjectSearch.ts`

3. **useProjectFilters** (218 行)
- 功能:项目过滤、排序和统计
- 包含:类型过滤、状态过滤、语言过滤、排序逻辑
- 文件:`src/views/HomeView/composables/useProjectFilters.ts`

#### 阶段2: 交互与显示(3个 composables,-313 行)

4. **useProjectOpenState** (167 行)
- 功能:项目和终端打开状态管理
- 特性:最短可见时长防闪烁逻辑
- 文件:`src/views/HomeView/composables/useProjectOpenState.ts`

5. **useVirtualScroll** (139 行)
- 功能:虚拟滚动增量渲染
- 优化:提高大列表初始渲染性能
- 文件:`src/views/HomeView/composables/useVirtualScroll.ts`

6. **useProjectMenus** (159 行)
- 功能:项目右键菜单构建
- 包含:编辑器选择菜单、项目操作菜单
- 文件:`src/views/HomeView/composables/useProjectMenus.ts`

#### 阶段3: 导航管理(1个 composable,-48 行)

7. **useProjectNavigation** (88 行)
- 功能:滚动位置记忆和导航
- 特性:支持列表/卡片两种布局独立状态
- 文件:`src/views/HomeView/composables/useProjectNavigation.ts`

## 代码质量提升

### 1. 可读性

- **前**:2745 行的单一文件,需要大量滚动查找功能
- **后**:7 个职责明确的 composables,每个文件独立管理特定功能

### 2. 可维护性

- 每个 composable 都有清晰的文档注释
- 依赖关系明确,通过参数注入
- 状态管理集中,避免分散的响应式变量

### 3. 可测试性

- Composables 可以独立测试,无需挂载整个组件
- 依赖注入使得 mock 更容易
- 每个 composable 有明确的输入输出

### 4. 可复用性

- `useDisplayPathCache` 可用于其他需要路径显示的组件
- `useProjectSearch` 的 Fuse.js 封装可复用
- `useVirtualScroll` 可用于其他大列表场景

## 技术亮点

### 1. 依赖注入模式

```typescript
export function useProjectMenus(deps: MenuDependencies) {
const { t, editorHasLaunchCommand } = deps
// ...
}
```

通过接口定义依赖,而不是直接导入 stores,提高了可测试性。

### 2. 智能索引缓存

```typescript
// useProjectSearch.ts
// 只在搜索相关字段变化时重建索引
const indexKey = computed(() =>
projects.value.map(p => `${p.appendTime}:${p.name}:${p.path}:${p.mainLang}:${p.group}`).join('|')
)
```

避免无关更新(如 `isExists`)触发昂贵的索引重建。

### 3. 防抖优化

```typescript
// useProjectSearch.ts
// 100ms 防抖,减少搜索计算
const debouncedSearchValue = ref('')
const searchDebounceTimer: ReturnType<typeof setTimeout> | null = null
```

### 4. 最短可见时长防闪烁

```typescript
// useProjectOpenState.ts
// 确保 loading 图标至少显示 2200ms,避免快速闪烁
const MIN_PROJECT_OPENING_VISIBLE_MS = 2200
```

### 5. 虚拟滚动

```typescript
// useVirtualScroll.ts
// 列表初始渲染 160 项,卡片初始渲染 72 项
// 通过 IntersectionObserver 实现按需加载
```

## Git 提交历史

```
71ebbe8 refactor(home): extract useProjectMenus composable
2b4e487 refactor(home): extract useProjectNavigation composable
91cf6ae refactor(home): extract useVirtualScroll composable
ec29f4c refactor(home): extract useProjectOpenState composable
e2d3d91 refactor(home): extract useProjectFilters composable
c8b358f refactor(home): extract useProjectSearch composable
30c58ee refactor(home): extract useDisplayPathCache composable
ea69e6e refactor(home): create composables directory
```

## 验证结果

所有检查通过:
- ✅ TypeScript 类型检查 (`pnpm typecheck`)
- ✅ ESLint 代码规范 (`pnpm lint`)
- ✅ 前端单元测试 (`pnpm test`)
- ✅ Rust 测试 (`pnpm test:rust`)

## 未来改进方向

### 1. 继续拆分

剩余的项目操作逻辑(~200 行)可以提取为 `useProjectActions`:
- `openProject`
- `openProjectWithEditor`
- `openRemoteProjectWithEditor`
- `openProjectInTerminal`
- `copyProjectPath`
- `handleProjectMenuSelect`

### 2. 测试覆盖

为每个 composable 编写单元测试:
- `useProjectSearch.test.ts` - 测试模糊搜索逻辑
- `useProjectFilters.test.ts` - 测试过滤和排序
- `useVirtualScroll.test.ts` - 测试虚拟滚动加载

### 3. TypeScript 优化

添加更严格的类型定义:
- Composable 返回值类型
- 事件处理器类型
- 泛型约束

## 总结

这次重构成功地将 HomeView.vue 从单一巨型组件拆分为多个职责明确的 composables,在保持功能完整的同时,显著提升了代码的可读性、可维护性和可测试性。重构过程中没有引入任何功能回归,所有现有功能正常工作。

**关键成果:**
- 减少 HomeView.vue **21.5%** 的代码量
- 提取 **7 个可复用 composables**
- 提高代码质量和可维护性
- 为未来功能扩展打下良好基础
1 change: 1 addition & 0 deletions icons/trae-color.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn run() {
project::export_projects,
project::import_projects,
project::open_project,
project::open_remote_project,
project::read_project_license,
scanner::detect_cli_history_root_path,
scanner::detect_jetbrains_config_root_path,
Expand Down
Loading
Loading