Vue 表单计算器整页跳转丢参数 (location.href Query Param Lost After Full Page Reload)
触发条件
- 传统多页思路写进 Vue SPA:点击"计算"用
location.href = "?param=value"做整页跳转,期望刷新后从 URL 读参数渲染结果。 - 配套的全局变量在页面模板里写死为
null(如var birthday = null;),而 JS 文件直接引用该全局变量初始化表单。 - 页面没有任何代码调用
c.urlParam()/URLSearchParams读取location.search。 - 结果展示区(
.compute-result)甚至从未写进 HTML,只在 CSS 里定义了样式。
症状
- 点击"计算"后页面闪一下(整页刷新),输入框清空,结果永远不显示。
- 用户感知是"点击没反应",因为刷新回到的是同一张空白表单。
- 手动访问
/page?param=value也不会出结果,因为参数没人读。
容易误判的方向
- 以为是日期选择器组件或 Element Plus 版本问题。
- 以为
validate回调没执行(实际执行了,只是里面只有一句跳转)。 - 只改 JS 加回跳转逻辑,没发现刷新侧本来就缺"读参数"的代码,怎么跳都是死循环。
- 检查了 Vue 挂载却漏了 HTML 里根本没有结果区块。
根因
原站(如 tool.6767.chat 系工具页)的服务端渲染时代逻辑残留:服务端模板会解析 query 参数并注入 var birthday = "..."。静态化/自托管后服务端注入消失,前端却仍按"提交→刷新→读参数"的旧契约工作,两侧契约都断了:
location.href = "?birthday=..."触发整页重新加载,Vue 应用销毁重建。- 重建时
formData.birthday = birthday,而birthday写死null。 mounted()里if (!c.isNullOrEmpty(this.formData.birthday))不成立,结果区不渲染。
最终解决原则
单页计算器不需要"跳转传参"这层 router 机制,直接页内计算:
compute()在validate通过后直接调用计算方法更新响应式字段,不碰location.href。- 把"当前时间"直接用
new Date()取(纯前端工具无需 API 或环境变量),日期差计算保持纯函数。 - 分享链接能力用
history.replaceState(null, "", "?birthday=...")保留:不刷新页面,但 URL 同步参数,复制链接/收藏/刷新都能还原结果。 mounted()里用c.urlParam("birthday")读入站参数并自动计算,兼容旧分享链接。- 结果区块用
v-cloak+v-if="结果!=null"防闪现。 setInterval倒计时类副作用要存句柄并在beforeUnmount清理;重复计算时先clearInterval旧句柄再建新的,避免计时器叠加。
验证方法
node --check逐个过改动的 JS 文件。无头浏览器(Edge
--headless=new+ CDPRuntime.evaluate)三组断言:- 无参进入 → 填输入 →
click()计算按钮 →.compute-result有文本、location.search已被 replaceState 同步、无导航发生。 - 改值再点一次 → 结果更新、计时器不叠加。
- 直接访问带参 URL → 结果自动渲染、输入框回填。
- 无参进入 → 填输入 →
grep -rn 'location.href = "?'" js/tools/确认无残留旧模式。
识别口诀
SPA 里见 location.href = "?..." 当提交,先问刷新侧谁在读参数;没人读就是断链,改成页内计算加 replaceState。
相关概念
- SPA 单页应用路由 (SPA Routing)
- History API 与 replaceState (History API and replaceState)
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Frontend