- 添加模板管理故障排除清单,以帮助用户解决模板管理中遇到的常见问题。 - 统一服务注入逻辑,移除不必要的props定义,增强错误处理机制。 - 优化模板管理,统一服务注入与存储键管理。 - 更新 `TemplateSelect.vue`,移除 `services` prop,改用 `inject` 注入服务。 - 整合 `useTemplateManager`,统一模板选择保存逻辑及存储键管理。 - 新增 `storage-keys.ts`,集中管理存储键常量,避免重复定义,便于维护与遍历。 - 更新相关组件以适配新的模板管理方式,确保模板选择状态正确保存和恢复。 - 修正了模板类型错误的问题,确保在管理界面切换分类后添加的模板类型与当前显示的分类一致。 - 修复了模板管理器打开位置错误的问题,确保从不同入口打开模板管理器时,定位到正确的分类。 - 优化了模板保存和导入逻辑,增加了错误处理和提示。 - 确保所有异步模板操作都使用了 `await` 关键字,避免潜在的时序问题。 - 移除了 `usePromptOptimizer` 中 `selectedOptimizationMode` 的默认值,强制传入该参数。 - 优化了 `TemplateSelect` 组件中 `optimizationMode` prop 的处理,设为 `required`。
5.0 KiB
5.0 KiB
Vue Composable 架构重构实施记录
📋 任务概述
解决在异步回调中调用 Vue Composable 函数导致的错误:Uncaught (in promise) SyntaxError: Must be called at the top of a 'setup' function。重构所有 Composable 文件,实现"顶层声明,响应式连接,内部自治"的设计模式。
🎯 目标
- 解决 Vue Composable 调用时机问题
- 建立统一的服务接口定义
- 实现响应式的服务依赖注入
- 提高代码一致性和可维护性
📅 执行记录
✅ 已完成步骤
1. 创建统一的服务接口定义
- 完成时间: 2025-07-05 上午
- 实际结果: 成功创建
packages/ui/src/types/services.ts文件,定义AppServices接口 - 经验总结: 中心化类型定义提高了代码一致性和可维护性
2. 重构核心 Composable 文件
- 完成时间: 2025-07-05 下午
- 实际结果: 成功重构 8 个主要 Composable 文件,使其接收
services: Ref<AppServices | null>参数 - 经验总结: 统一的参数模式使代码更加一致,易于理解
3. 更新 useAppInitializer
- 完成时间: 2025-07-05 晚上
- 实际结果: 增强了错误处理和日志记录,添加了
error状态 - 经验总结: 良好的错误处理对调试至关重要
4. 更新 useModals
- 完成时间: 2025-07-05 晚上
- 实际结果: 将 useModals 也纳入新架构,接收 services 参数
- 经验总结: 保持架构一致性对于长期维护非常重要
5. 更新文档
- 完成时间: 2025-07-05 晚上
- 实际结果: 更新了架构文档和经验记录
- 经验总结: 及时记录架构决策和经验对团队知识传承很重要
⚠️ 待解决问题
6. 更新 App.vue
- 进行中: 2025-07-06
- 当前状态: 遇到类型错误,需要进一步解决
- 问题记录:
services对象与AppServices接口不匹配,特别是dataManager属性- 尝试使用类型断言
as any临时解决,但仍有类型错误 - 需要进一步研究
DataManager类型定义和实现
🔧 核心解决方案
架构模式
// ❌ 错误:在异步回调中调用Composable
onMounted(async () => {
const services = await initServices();
const modelManager = useModelManager(); // 错误:不在setup顶层调用
});
// ✅ 正确:顶层声明,响应式连接
const { services } = useAppInitializer(); // 在顶层调用
const modelManager = useModelManager(services); // 在顶层调用,传入services引用
// 内部实现:响应式连接
export function useModelManager(services: Ref<AppServices | null>) {
// 状态定义...
// 响应式连接:监听服务就绪
watch(services, (newServices) => {
if (!newServices) return;
// 使用已就绪的服务...
}, { immediate: true });
return { /* 返回状态和方法 */ };
}
服务接口定义
// packages/ui/src/types/services.ts
export interface AppServices {
storageProvider: IStorageProvider;
modelManager: IModelManager;
templateManager: ITemplateManager;
historyManager: IHistoryManager;
dataManager: DataManager;
llmService: ILLMService;
promptService: IPromptService;
}
📊 进展状态
核心目标 80% 达成:
- ✅ 解决了
Must be called at the top of a 'setup' function错误 - ✅ 实现了统一、可预测的 Composable 设计模式
- ✅ 提高了代码的可维护性和健壮性
- ✅ 完成了全面的文档更新
- ❌ App.vue 中的类型错误仍需解决
技术实现:
- 创建了中心化的
AppServices接口 - 重构了 9 个 Composable 文件,使用统一的参数模式
- 增强了
useAppInitializer的错误处理和日志记录 - 采用了"快速失败"模式,提早暴露潜在问题
架构特点:
- 所有 Composable 在
<script setup>顶层调用 - Composable 接收
services: Ref<Services | null>参数 - 内部通过
watch(services, ...)响应服务就绪 - 明确的单向依赖关系
🎯 下一步计划
-
解决 App.vue 类型错误:
- 深入研究
DataManager类型定义和实现 - 检查
useAppInitializer返回的对象结构 - 可能需要调整
AppServices接口或服务实现
- 深入研究
-
添加错误处理UI:
- 利用
useAppInitializer返回的error状态 - 添加友好的错误提示界面
- 利用
-
编写架构指南:
- 为新开发人员创建详细的架构指南
- 说明 Composable 的正确使用方式
💡 核心经验总结
- Vue 响应式上下文: Vue Composable 必须在
<script setup>顶层同步调用 - 响应式连接模式: 使用
watch(services, ...)模式处理服务的异步初始化 - 快速失败原则: 在开发环境中,快速暴露问题比隐藏问题更有价值
- 统一架构: 保持所有 Composable 的一致架构模式
- 类型系统挑战: 复杂的类型系统可能导致接口不匹配问题
任务状态: ⚠️ 部分完成,需要解决类型错误
完成度: 80%
最后更新: 2025-07-01