前端开发日志(第 3 周)——结构优化 + 可配置化 + 可靠性与演示完善

0. 本周背景(为什么要“优化”)

到第 2 周结束,核心功能已经能跑:能创建会话、能推进、能在需要时完成狼人/女巫操作,并能看到 SSE 流式输出。但真实开发里,做到“能用”后通常会进入一个阶段:把代码与体验做得更稳定、更便于演示、更便于之后继续迭代。

因此第 3 周我把重点放在三件事:

  • 工程结构与可维护性:避免 Game.vue 继续膨胀,减少重复逻辑
  • 可配置与环境切换:解决 localhost:8000 写死的问题
  • 可靠性与用户反馈:把“只打印 console.error”提升到“用户看得懂的错误提示”,并补一些防呆

说明:本周内容以“真实迭代思路 + 基于你当前项目代码的改进点/做法”为主,符合课程项目中常见的第三周工作:重构、补体验、补稳定性。


1. 结构优化:把“流式执行”抽象出来(减少重复)

现在页面里有三处几乎一样的逻辑:

  • advanceStep():调用 advance(threadId, onMessage)
  • doWolfAction():调用 wolfAction(threadId, target, onMessage)
  • doWitchAction():调用 witchAction(threadId, save, poison, onMessage)

它们共同点都是:

1)把 store.loading=true
2)创建 streamState
3)在 token 回调里拼接消息
4)拿到最终 finalDatastore.setState(finalData.state, finalData.next)
5)finally 里关闭 loading

真实开发里,这种重复一般会抽成一个通用函数(比如 runStreamAction(actionFn)),或抽成 composable(如 useStreamRunner(store)),让 Game.vue 只保留“业务意图”,例如:

  • advanceStep:runStream(advance)
  • doWolfAction:runStream(() => wolfAction(…))

这样后面加“预言家行动”等新角色时,页面不会继续膨胀。


2. 可配置化:解决 baseURL 写死的问题(演示更稳)

目前项目真实情况是:

  • frontend/src/api.ts 里 axios baseURL 固定:http://localhost:8000
  • fetchStream() 里也直接拼了 fetch(\http://localhost:8000${url}`)`
  • Lobby.vue 的健康检查同样写死:fetch('http://localhost:8000/health')

这在课程演示时很容易翻车:如果老师电脑端口不是 8000,或者后端跑在局域网机器上,前端就全断。

我第 3 周的改进思路是:

  • baseURL 抽成一个配置来源(本地存储/环境变量/页面输入都行)
  • axios 与 fetch 都统一读取同一个 baseURL
  • Lobby 页加一个“服务地址”的输入框(默认 http://localhost:8000),写入 localStorage

对应到现有代码,至少要把下面这些“硬编码点”统一管理起来:

// api.ts(现有)
const API = axios.create({ baseURL: 'http://localhost:8000' })
fetch(`http://localhost:8000${url}`, ...)

// Lobby.vue(现有)
fetch('http://localhost:8000/health')

体会:课程项目最容易被忽略的就是“环境切换”。实际软件工程里,能不能稳定部署/稳定演示往往比多一个功能更重要。


3. 可靠性:从 console.error 到用户可理解的提示

当前前端很多地方捕获异常后只做 console.error(e)(例如 Lobby.vuestart/newSessionGame.vueadvanceStep/doWolfAction/doWitchAction)。

真实用户/验收老师不会打开控制台看错误,所以第 3 周我把“错误反馈”作为重点:

  • 请求失败时,给出可读提示(例如“后端未启动 / 地址不对 / 会话不存在”)
  • 对 404 state not found(后端真实返回)做提示:提示用户先回到大厅点击“进入游戏”或重新创建会话
  • 对女巫“同时使用两瓶药”的 400 提示:UI 侧增加互斥/或在提交前弹窗确认

后端真实错误点(server.py):

  • /state:无 state 会 404(state not found
  • /action/witch:save 和 poison 同时给会 400(cannot use both potions

把这些异常“翻译成用户语言”,会让演示更顺畅。


4. 交互防呆:让状态机更“好推进”

第 2 周我实现了“继续推进”按钮,但用户可能会遇到:

  • 不知道什么时候该点“继续推进”
  • 点太快导致重复请求(虽然有 loading 遮罩,但仍需要细节处理)
  • 刷新页面后 store 丢了 state(threadId 有持久化,但 state 需要重新 getState)

基于现有 Game.vue 已有的 refresh()(真实存在但尚未绑定 UI),第 3 周我会把它正式作为“恢复现场”的手段:

async function refresh() {
  const res = await getState(store.threadId)
  store.setState(res.state, res.next)
}

并把思路调整为:

  • 进入 Game 页时如果已有 threadId,先 getState() 恢复
  • 如果 getState 404,提示“会话不存在,回大厅创建新会话”

这在课程演示里非常关键:老师经常会随手刷新页面或返回再进入,如果前端无法恢复就会显得“不稳定”。


5. UI 细节打磨(课程项目很实用)

这一周我会把 UI 重点放在“演示友好”:

  • 顶部阶段/身份 tag 已有(第 2 周完成),本周补充更明确的提示(比如:需要行动时高亮“你的回合”)
  • 消息区增加“自动滚动策略”(用户在底部才自动滚到底,避免读历史消息时被拉走)
  • “AI 思考记录(上帝视角)”在演示时很加分,但也要注意:它是调试功能,后续可以加开关(默认折叠),避免信息过载

6. 本周总结与体会(更像大学生项目总结)

做完三周后,我对前端开发的理解更实际了:

  • 第一周偏“把路修通”:工程化、路由、store、接口先打通,保证最小闭环能跑。
  • 第二周偏“把车跑起来”:核心交互(推进/行动)+ SSE 流式体验,让玩法成立。
  • 第三周偏“让车更可靠”:抽重复逻辑、做可配置化、补错误提示与防呆,让演示更稳、代码更能继续迭代。

我最大的体会是:课程项目看起来是“功能越多越好”,但真实开发往往是“能不能稳定跑、能不能让别人看懂、能不能持续改”。把 baseURL 抽出来、把错误提示做好、把重复逻辑收敛,这些工作不炫技,但最能体现软件工程思维。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐