- 修复模型配置持久化问题,使用 localStorage 持久化模型配置。 - 区分禁用和删除操作: - 禁用:保留配置但暂时不可用,可以重新启用。 - 删除:完全移除配置,需要重新添加。 - 默认模型只能禁用不能删除,自定义模型可以禁用也可以删除。 - UI 上用不同的样式区分禁用和删除操作。 - 更新了 llmService 的方法,增加了 enableModel, disableModel, deleteModel 方法。 - 更新 ModelManager 组件,支持启用、禁用和删除模型。 - 更新 App.vue 和 InputPanel.vue 组件,同步模型状态。 - 增加了错误处理和用户反馈。 - 增加了 CSS 样式优化。
13 KiB
13 KiB
经验文档
API 集成最佳实践
架构设计
- 配置与业务逻辑分离,便于扩展支持更多模型
- API 配置统一接口格式 (endpoint、认证、请求/响应格式)
- 提示词模板单独管理,支持多语言
- 统一的错误处理机制
认证处理
- URL 参数认证 (如 Gemini)
- Header 认证 (如 DeepSeek Bearer Token)
- 封装统一的认证处理机制
数据处理
- 注意不同模型的请求格式差异
- 确保数据结构完整性
- 使用类型定义约束数据结构
- 响应格式统一解析
- 参数标准化 (temperature、max_tokens 等)
代码重构原则
模块化设计
- 明确模块职责边界
- 避免功能重复实现
- 合理拆分功能模块
- 保持接口一致性
依赖管理
- 统一的导入导出路径
- 检查所有引用点
- 确保函数单一定义
- 注意初始化顺序
错误处理
- UI 层负责错误展示
- 服务层继续传递错误
- 添加合适的日志
- 使用 loading 状态防止重复提交
项目结构规范
目录组织(src)
- api/: 外部 API 封装
- services/: 业务逻辑
- config/: 配置文件
- components/: UI 组件
- prompts/: 提示词模板
代码迁移
- 确认新实现完整性
- 检查所有依赖引用
- 完整更新所有调用点
- 保留迁移记录
开发环境说明
环境
- 当前使用windows系统,执行命令注意是windows命令,而非linux命令
Vue 组件开发
- 事件处理函数命名匹配
- 异步操作统一处理
- 模板字符串正确使用
- 状态管理规范化
- 下拉框样式优化:
- 使用 min-w-[width] 确保足够宽度
- 自定义下拉箭头使用内联 SVG 作为背景图片
- 使用 appearance-none 移除默认样式
- 合理设置内边距确保文本显示完整
LLM API 统一化经验
统一接口设计
- 使用 OpenAI 格式作为标准接口
- 将不同模型的差异封装在配置层
- 支持动态添加新模型
- 环境变量自动初始化模型状态
模型配置管理
- 统一的模型配置结构
- baseUrl: API 端点
- models: 支持的模型列表
- defaultModel: 默认模型
- authType: 认证类型 (bearer/query)
- enabled: 启用状态
- 支持自定义模型配置
- API 密钥安全存储
- 动态模型启用/禁用
- 禁用和删除的区别:
- 禁用是暂时的状态改变,保留配置以便重新启用
- 删除是永久性的操作,完全移除配置
- 默认模型只能禁用不能删除
- 自定义模型可以禁用也可以删除
- UI 上应该用不同的样式区分这两种操作
模型配置持久化
- 配置持久化是必需的功能,不能依赖内存状态
- 禁用和删除是不同的操作:
- 禁用:保留配置但暂时不可用,可以重新启用
- 删除:完全移除配置,需要重新添加
- 需要持久化的内容:
- 模型配置(包括自定义模型)
- API密钥
- 当前选择的模型
- 启用/禁用状态
- 使用 localStorage 时注意:
- 保存前做数据校验
- 读取时做数据兼容性处理
- 考虑清理机制避免存储过大
请求处理标准化
- 统一的消息格式
- system: 系统提示词
- user: 用户输入
- 统一的请求参数
- temperature
- max_tokens
- 统一的响应解析
- 错误处理标准化
用户界面优化
- 动态模型选择列表
- 模型配置管理界面
- 启用状态可视化
- 配置保存反馈
模型管理经验
模型启用/禁用状态管理
-
状态显示
- 禁用的模型不应从列表中删除,而是应该保留并显示禁用状态
- 这样用户可以随时查看和重新启用已禁用的模型
- 使用视觉差异(如颜色、标签)来区分启用和禁用状态
-
API 设计经验
- 服务层方法命名要准确反映其功能,例如:
getAllModels(): 获取所有模型,包括已禁用的enableModel(): 启用模型disableModel(): 禁用模型
- 避免在服务层过滤数据(如只返回已启用的模型),而是在应用层面进行过滤
- 这样可以保持服务层 API 的通用性和灵活性
- 让调用方决定如何使用和过滤数据
- 服务层方法命名要准确反映其功能,例如:
-
状态变更注意事项
- 当修改核心服务的 API 时,需要同步更新所有依赖的组件
- 在本例中,我们修改了
llmService的方法,需要更新:- ModelManager.vue:模型管理界面
- App.vue:初始化逻辑
- InputPanel.vue:模型选择器
- 建议在修改服务 API 时,先全局搜索所有使用点,确保完整更新
-
错误处理最佳实践
- 在 API 调用处进行错误处理
- 提供有意义的错误信息,帮助定位问题
- 考虑错误的连锁反应,例如初始化失败后的后续操作处理
环境配置最佳实践
.env.local文件用于存储本地环境变量和敏感信息- 应该创建
.env.example作为模板文件并提交到仓库 - 环境文件应该在
.gitignore中明确列出 - 常见的环境文件模式:
- .env.local
- .env.*.local
- .env.development.local
- .env.test.local
- .env.production.local
三栏布局最佳实践
布局设计
- 使用 CSS Grid 实现响应式布局
- 移动端自动切换为单列布局
- 合理设置列间距和内边距
- 使用 min-height 确保内容区域高度
组件拆分
- 按功能模块拆分组件
- 保持组件职责单一
- 使用 props/emit 进行组件通信
- 统一的样式和交互模式
状态管理
- 将共享状态提升到父组件
- 使用 v-model 实现双向绑定
- 异步操作状态独立管理
- 错误状态统一处理
交互优化
- 添加合适的加载状态
- 实现一键复制功能
- 优化表单验证反馈
- 添加必要的提示信息
界面优化经验
提示词优化器优化要点
-
模型选择
- 优化和测试可以使用不同的模型
- 下拉框宽度应根据模型名称动态调整
- 默认选择第一个可用模型
-
提示词展示
- 使用可调整大小的文本区域
- 设置合理的最小和最大高度
- 添加拖动手柄样式提示
- 保持滚动条功能但隐藏其显示
-
交互逻辑
- 优化后的提示词自动用于测试
- 如果没有优化结果,使用原始提示词
- 移除多余的确认按钮
- 保持界面简洁直观
常见问题修复
-
API 方法命名
- chat -> sendMessage:更准确地描述功能
- 保持方法命名的一致性和语义化
- 在修改方法名时同步更新所有调用点
-
组件样式
- 使用 resize-y 实现可调整大小
- 使用 min-height 和 max-height 控制尺寸范围
- 使用 overflow-auto 处理内容溢出
- 保持边框颜色与主题一致
-
状态管理
- 提示词状态和测试状态分开管理
- 使用 watch 监听属性变化
- 合理设置默认值
- 及时清理和重置状态
错误处理和用户反馈经验
错误处理最佳实践
-
错误信息显示
- 不要只在控制台打印错误,要通过 UI 显示给用户
- 错误信息应该具体且有指导性,例如:
- ❌ "操作失败"
- ✅ "启用模型失败: 模型 openai 缺少 API 密钥"
- 使用 Toast 组件显示临时性的成功/错误提示
-
错误处理层级
- 在服务层(如 llmService)抛出具体的错误
- 在组件层捕获并展示给用户
- 保持错误信息在传递过程中的完整性
-
操作反馈的完整性
- 成功操作也要有反馈,例如:
- 保存成功
- 删除成功
- 添加成功
- 反馈要即时,不能有延迟
- 使用适当的视觉提示(颜色、图标等)
- 成功操作也要有反馈,例如:
-
UI 状态同步
- 当一个操作影响多个组件时,确保所有相关组件都得到更新
- 例如:禁用模型后,需要:
- 更新模型列表的显示状态
- 更新所有使用该模型的选择器
- 如果当前选中的是被禁用的模型,自动切换到其他可用模型
-
UI 一致性
- 相似的操作应该有相似的反馈方式
- 统一使用相同的提示组件(如 Toast)
- 保持视觉样式的一致性,例如:
- 所有下拉框使用相同的样式
- 去除浏览器默认样式(如双重下拉箭头)
组件设计经验
-
组件通信
- 使用事件(emit)通知父组件状态变化
- 父组件负责协调多个子组件的状态同步
- 避免子组件直接修改父组件的状态
-
可复用性
- 将通用的功能(如 Toast)封装为可复用的组合式函数
- 在多个组件中保持一致的使用方式
- 统一的错误处理模式便于维护和扩展
Vue 组件开发最佳实践
Props 和 v-model 使用
-
Props 是只读的
- 不能直接使用 v-model 绑定 props
- 应该使用 :value 绑定
- 需要修改时使用 emit 发送事件
-
双向绑定的正确实现
- 父组件使用 v-model
- 子组件使用 :value 和 @input
- 或者使用计算属性的 get/set
- 明确声明 emit 事件
-
常见错误修复
<!-- 错误用法 --> <textarea v-model="propValue"></textarea> <!-- 正确用法 --> <textarea :value="propValue" @input="$emit('update:propValue', $event.target.value)" ></textarea> -
只读场景优化
- 使用 :value 单向绑定
- 添加 readonly 属性
- 不需要 emit 事件
- 保持代码简洁
UI设计经验
深色主题设计
-
背景色使用
- 主背景使用深色(如 bg-gray-900)
- 卡片背景使用半透明黑色(bg-black/20)
- 避免纯黑色,使用略带色调的深色
-
文本颜色
- 主要文本使用 90% 不透明白色(text-white/90)
- 次要文本使用 60% 不透明白色(text-white/60)
- 占位符文本使用 30% 不透明白色(placeholder-white/30)
- 避免使用纯白色,降低对比度提高可读性
-
边框和分割线
- 使用半透明边框(border-purple-600/50)
- 边框圆角使用统一尺寸(rounded-xl)
- 分割线使用低透明度(border-purple-700/20)
-
交互元素
- 按钮使用渐变或半透明背景
- 悬停状态增加透明度或亮度
- 添加过渡动画提升体验(transition-colors)
- 禁用状态降低透明度(opacity-50)
-
输入框样式
- 使用半透明背景区分层次
- 添加内边距确保文本不贴边
- 聚焦状态使用发光效果(ring-2)
- 保持边框颜色与主题一致
-
布局考虑
- 合理使用间距和留白
- 使用阴影增加层次感
- 保持视觉层次的一致性
- 注意元素间的对比度
响应式设计
- 使用 CSS Grid 实现响应式布局
- 移动端自动切换为单列布局
- 合理设置列间距和内边距
- 使用 min-height 确保内容区域高度
常见问题修复
-
深色主题下文本不清晰
/* 错误示范 */ .text-input { background: transparent; } /* 正确做法 */ .text-input { background: rgba(0, 0, 0, 0.3); color: rgba(255, 255, 255, 0.9); } -
弹性布局空间分配问题
/* 错误示范 */ .flex-container { height: 100%; } /* 正确做法 */ .flex-container { min-height: 0; flex: 1; } -
下拉框内容截断
/* 错误示范 */ .select { width: auto; } /* 正确做法 */ .select { min-width: max-content; padding-right: 2rem; }
CSS 样式经验
Select 元素样式定制
-
移除默认样式的正确方法
.custom-select { -webkit-appearance: none !important; -moz-appearance: none !important; appearance: none !important; background-image: none !important; } .custom-select::-ms-expand { display: none; }-
❌ 常见错误做法:
- 只使用
appearance: none类 - 只添加内联样式
- 不处理 IE 浏览器的特殊情况
- 只使用
-
✅ 最佳实践:
- 使用
!important确保样式优先级 - 同时处理 webkit、moz 和标准属性
- 显式移除背景图像
- 处理 IE 浏览器的
::-ms-expand - 将样式定义在全局 CSS 中而不是内联
- 使用
-
-
样式复用和维护
- 将通用样式抽取为独立的类(如
.custom-select) - 避免在多个组件中重复定义相同的样式
- 使用语义化的类名便于维护
- 将通用样式抽取为独立的类(如
-
样式调试经验
- 当样式不生效时,检查:
- 浏览器特定前缀是否完整
- 样式优先级是否足够
- 是否有其他样式覆盖
- 使用浏览器开发工具检查计算后的样式
- 当样式不生效时,检查:
-
跨浏览器兼容性
- 不同浏览器对 select 元素的默认样式处理不同
- 需要同时处理现代浏览器和 IE 的特殊情况
- 测试所有主流浏览器确保样式一致