解决在异步回调中调用 Vue Composable 函数导致的错误:Uncaught (in promise) SyntaxError: Must be called at the top of a 'setup' function。重构所有 Composable 文件,实现"顶层声明,响应式连接,内部自治"的设计模式。
- 解决 Vue Composable 调用时机问题
- 建立统一的服务接口定义
- 实现响应式的服务依赖注入
- 提高代码一致性和可维护性
- 完成时间: 2025-07-05 上午
- 实际结果: 成功创建
packages/ui/src/types/services.ts文件,定义AppServices接口 - 经验总结: 中心化类型定义提高了代码一致性和可维护性
- 完成时间: 2025-07-05 下午
- 实际结果: 成功重构 8 个主要 Composable 文件,使其接收
services: Ref<AppServices | null>参数 - 经验总结: 统一的参数模式使代码更加一致,易于理解
- 完成时间: 2025-07-05 晚上
- 实际结果: 增强了错误处理和日志记录,添加了
error状态 - 经验总结: 良好的错误处理对调试至关重要
- 完成时间: 2025-07-05 晚上
- 实际结果: 将 useModals 也纳入新架构,接收 services 参数
- 经验总结: 保持架构一致性对于长期维护非常重要
- 完成时间: 2025-07-05 晚上
- 实际结果: 更新了架构文档和经验记录
- 经验总结: 及时记录架构决策和经验对团队知识传承很重要
- 进行中: 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