Vue 2.7.16's Final Patch Broke v-show When Combined With Inline Styles
That Page That Was Never Changed — Why Did It Suddenly Break?
Vue 2.7.16 / v-show and style / lock files
Background
The project hadn't been touched in a long time. The task name in the navigation task panel was controlled with v-show="isRunning", with a style="display: flex" next to it. It had been written that way for years and always worked fine.
Today it suddenly broke.
Testing sent a screenshot: the task had ended, isRunning was false, but the task name was still hanging on the panel.
Q: Was this part changed? A: No. Q: Then why did it suddenly break?
That question is annoying to hear, but it really had to be investigated.
Investigation
First, suspect yourself.
Open StartTask.vue:
<div
v-show="isRunning"
class="gcs-radius"
style="display: flex; justify-content: center"
>
Check the data: isRunning is indeed false after the task ends.
Check updates: the component re-renders.
Check styles: no extra display is written elsewhere.
Clear cache, clear node_modules, restart the service — still reproducible.
Check the business logic again: the state flow for ending tasks is also fine.
A bit strange. When the v-show condition is false, it simply adds display: none to the element. How could something so fundamental suddenly fail?
Narrowing It Down
Create a minimal reproduction:
<div v-show="visible" style="display: flex">Content</div>
<button @click="visible = !visible">toggle</button>
Click it, and it doesn't hide when it should.
Remove style, keep only v-show — works fine.
Remove v-show, keep only style — works fine.
Both together — broken.
The conclusion is clear: it's not the business logic that's broken; it's a conflict between v-show and style on the same tag.
But this still doesn't explain why it worked fine before and only exploded today. The same pattern had lived in the project for a long time.
The Real Reason
The code didn't change, so check if the runtime environment changed.
In package.json:
"vue": "^2.7.14"
Note the ^. It allows installing updates within the compatible range. For 2.7.x, ^2.7.14 can resolve to 2.7.15, 2.7.16.
Now check the actually installed version:
vue@^2.7.14:
version "2.7.16"
Things start to make sense.
The project hadn't been touched for a long time. The node_modules on the old computer was still the version installed back then, most likely 2.7.14 or 2.7.15. Running locally every day, the page was fine.
Today, a new computer was set up, the code was pulled, and dependencies were reinstalled. package.json still says ^2.7.14, but the package manager, following the rules, installed the latest official version within range: 2.7.16.
Not a single line of code changed. Vue jumped a minor version, and the behavior changed.
What Changed in 2.7.16
Vue 2.7.16, codenamed Swan Song, is the final official release of Vue 2. No new features, mainly closing bug fixes and aligning some types with Vue 3.
One of them:
style: always set new styles
To fix style merging issues (like border and border-bottom overwriting each other), 2.7.16 removed the check that skipped setting when the new and old values were the same. Now, every update rewrites all properties in the style object.
The actual effect is:
v-show=falsefirst writesdisplay: none- In the same update cycle, the style module runs again
- The inline
stylehasdisplay: flex setProp(el, 'display', 'flex')overwrites thenone
Thus, v-show fails, and the element is displayed again.
Official issue: vuejs/vue#13140. Someone submitted a fix PR, but Vue 2 is already EOL and will not receive any more patches.
So it's not that the directive was written wrong; it's a regression introduced upstream to fix A, which happened to hit B. We only saw it today because the new environment ran 2.7.16 for the first time.
About Lock Files
Looking back, what's more worth remembering than changing the template is this:
package.json specifies a version range. Which version is actually installed depends on the lock file.
If the lock file is committed and used seriously:
- The old computer and the new computer will install the same
vue - Situations where it works locally but is broken in someone else's environment will be much rarer
- Upgrades become an explicit change, not something brought along when reinstalling dependencies
The real hidden reason this time boils down to one sentence: the page didn't suddenly break; it was the first time 2.7.16 was installed after switching computers.
So, commit the lock file. Don't treat it as optional.
Solutions
1. Downgrade to 2.7.15
The most direct. On 2.7.15, v-show won't be overwritten by style.
The cost is losing other fixes in 2.7.16 (keep-alive leaks, some reactivity edge cases, type alignment, etc.). Suitable for a temporary stopgap, not ideal for staying here long-term.
2. Replace v-show with v-if
<div
v-if="isRunning"
class="gcs-radius"
style="display: flex; justify-content: center"
>
A small change, takes effect immediately. The element will be destroyed and recreated. Generally fine for normal UI; be a bit careful with maps, charts, or components with lots of internal state.
3. Change static style to a class
<div v-show="isRunning" class="gcs-radius task-name-row">
.task-name-row {
display: flex;
justify-content: center;
}
v-show writes an inline display: none, which has higher priority than the display: flex in the stylesheet and won't be overwritten. The layout is also cleaner.
We used solution 2 for the task panel and extracted display: flex into a class for the plan management dialog, using solution 3. Just choose based on the scenario.
Summary
The investigation is over, and the code changes aren't large.
Next time you encounter something that was never changed but suddenly broke, you can first ask: is the version you installed still the same one?
Related Links
- Issue: Using v-show and :style simultaneously does not yield expected results in 2.7.16
- Root cause commit: fix(style): always set new styles
- Unmerged fix attempt: PR #13198
- Vue 2 EOL announcement: Vue 2 End of Life
This article is based on real project experience, with the outline drafted manually and AI-assisted polishing, on 2026-07-13
Top 2 of 3 from juejin.cn, machine-translated. The original thread is authoritative.
lock files must be included
Yes.
Good article, thanks for sharing.