那个从没改过的页面,为什么突然坏了? 背景 项目很久没有动过。走航任务面板中的任务名称,通过 v-show="isRunning" 控制显示,旁边配有 style="display: flex",这一写法持续了多年,始终运行正常。 然而,今天突然出现问题。 测试人员发来截图:任务已经结束,isRun

项目很久没有动过。走航任务面板中的任务名称,通过 v-show="isRunning" 控制显示,旁边配有 style="display: flex",这一写法持续了多年,始终运行正常。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
然而,今天突然出现问题。
测试人员发来截图:任务已经结束,isRunning 为 false,但任务名称仍旧显示在面板上。
问:这块代码改动过吗?
答:没有。
再问:那为什么突然失效了?
这个问题听起来令人困扰,但确实需要排查。
首先怀疑自身代码。
打开 StartTask.vue:
复制代码
检查数据:isRunning 在结束任务后确实为 false。
检查更新:组件已重新渲染。
检查样式:其他位置没有额外定义 display 属性。
尝试清理缓存、删除 node_modules、重启服务,问题依然存在。
进一步跟踪业务逻辑:结束任务的状态流转也没有异常。
这让人感到奇怪。v-show 条件为假时,理应给元素添加 display: none,如此基础的功能怎么会突然失效?
缩小范围
制作最小复现样例:
复制代码内容
点击按钮,元素本应隐藏却未隐藏。
移除 style,仅保留 v-show,功能正常。
移除 v-show,仅保留 style,样式正常。
两者同时存在,异常出现。
结论明确:并非业务逻辑出错,而是同一标签上 v-show 和 style 发生了冲突。
但这仍无法解释为何过去一直正常运行,直到今天才暴露。相同的写法在项目中已存在很久。
真正的原因
代码未变,需确认运行环境是否变化。
package.json 中的配置为:
复制代码"vue": "^2.7.14"
注意这里的 ^ 符号。它允许在兼容范围内自动安装更新版本。对于 2.7.x 系列,^2.7.14 可解析到 2.7.15、2.7.16 等版本。
查看实际安装的版本:
复制代码vue@^2.7.14:
version "2.7.16"
至此,原因浮出水面。
项目长时间未更新。旧电脑上的 node_modules 仍是当时安装的版本,极可能是 2.7.14 或 2.7.15。每日运行,页面正常。
今天更换了新电脑,拉取代码后重新安装依赖。package.json 仍为 ^2.7.14,包管理器按照规则安装了该范围内的最新正式版 2.7.16。
一行代码未改,Vue 的小版本跳升一级,行为却发生了变化。
2.7.16 改了什么
Vue 2.7.16 代号 Swan Song,是 Vue 2 的最终正式版。该版本未引入新功能,主要用于收尾 bug 修复并与 Vue 3 对齐部分类型定义。
其中一项变更值得关注:
为解决样式合并问题(例如 border 与 border-bottom 相互覆盖),2.7.16 移除了新旧值相同时的跳过判断,每次更新都会将 style 对象中的属性重新写入。
实际影响如下:
v-show=false 先设置 display: none
- 在同一更新周期内,style 模块再次执行
- 内联
style 中包含 display: flex
- 执行
setProp(el, 'display', 'flex') 将 none 覆盖
最终导致 v-show 失效,元素再次显示。
官方 issue 见:vuejs/vue#13140。曾有人提交修复 PR,但 Vue 2 已停止维护,不会再发布补丁。
因此,问题并非指令编写错误,而是上游为修复 A 引入的回归恰好影响了 B。我们今天才发现,是因为新环境首次实际运行到了 2.7.16。
关于 lock 文件
复盘之后,比修改模板更值得铭记的是以下要点:
package.json 定义的是版本范围,实际安装的版本取决于 lock 文件。
若 lock 文件被认真提交并严格使用:
- 旧电脑与新电脑将安装相同的
vue 版本
- 本地正常而他人环境异常之类的推诿会大幅减少
- 版本升级会变为一次明确的变更,而不是重装依赖时意外附带
此次问题的真正隐藏原因仅一句:并非页面突然损坏,而是换电脑后首次安装到了 2.7.16。
因此,lock 文件务必提交,不应视为可有可无。
解决办法
1. 降级到 2.7.15
最直接的方案。在 2.7.15 上,v-show 不会被 style 覆盖。
代价是放弃 2.7.16 中的其他修复(如 keep-alive 泄漏、部分响应式边界、类型对齐等)。适合临时止血,不建议长期停留于此版本。
2. 将 v-show 替换为 v-if
复制代码
改动量小,立即可用。元素会销毁重建,普通 UI 通常无影响;但地图、图表、内部状态较多的组件需谨慎处理。
3. 将静态 style 改为 class
复制代码
复制代码.task-name-row {
display: flex;
justify-content: center;
}
v-show 设置的是内联 display: none,优先级高于样式表中的 display: flex,不会被覆盖。同时布局更清晰。
实际项目中,任务面板采用了方案 2,方案管理弹窗将 display: flex 提取为 class,使用了方案 3。可根据实际场景灵活选择。
小结
排查工作至此结束,代码改动不大。
今后再遇到从未动过却突然失效的页面,可以先问一句:你安装的,还是同一个版本吗?
相关链接
- Issue:Using v-show and :style simultaneously does not yield expected results in 2.7.16
- 根因 commit:fix(style): always set new styles
- 未合入的修复尝试:PR #13198
- Vue 2 EOL 说明:Vue 2 End of Life
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述
相关攻略
更多
同类更新
更多
热游推荐
更多
-
- DreamStudio
- Android/ | AI绘图
- 2026-06-30
下载
-
-
- Playground AI
- Android/ | AI绘图
- 2026-06-30
下载
-
- Adobe Firefly
- Android/ | AI绘图
- 2026-06-30
下载
-
-
-
- Leonardo AI
- Android/ | AI绘图
- 2026-06-30
下载
-
- Stable Diffusion
- Android/ | AI绘图
- 2026-06-30
下载