项目实训——Werewolf-Agent 多智能体狼人杀前端开发日志Vue3
前端开发日志(第 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)拿到最终 finalData 后 store.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:8000fetchStream()里也直接拼了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.vue 的 start/newSession、Game.vue 的 advanceStep/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()恢复 - 如果
getState404,提示“会话不存在,回大厅创建新会话”
这在课程演示里非常关键:老师经常会随手刷新页面或返回再进入,如果前端无法恢复就会显得“不稳定”。
5. UI 细节打磨(课程项目很实用)
这一周我会把 UI 重点放在“演示友好”:
- 顶部阶段/身份 tag 已有(第 2 周完成),本周补充更明确的提示(比如:需要行动时高亮“你的回合”)
- 消息区增加“自动滚动策略”(用户在底部才自动滚到底,避免读历史消息时被拉走)
- “AI 思考记录(上帝视角)”在演示时很加分,但也要注意:它是调试功能,后续可以加开关(默认折叠),避免信息过载
6. 本周总结与体会(更像大学生项目总结)
做完三周后,我对前端开发的理解更实际了:
- 第一周偏“把路修通”:工程化、路由、store、接口先打通,保证最小闭环能跑。
- 第二周偏“把车跑起来”:核心交互(推进/行动)+ SSE 流式体验,让玩法成立。
- 第三周偏“让车更可靠”:抽重复逻辑、做可配置化、补错误提示与防呆,让演示更稳、代码更能继续迭代。
我最大的体会是:课程项目看起来是“功能越多越好”,但真实开发往往是“能不能稳定跑、能不能让别人看懂、能不能持续改”。把 baseURL 抽出来、把错误提示做好、把重复逻辑收敛,这些工作不炫技,但最能体现软件工程思维。
更多推荐



所有评论(0)