File tree Expand file tree Collapse file tree 2 files changed +40
-1
lines changed Expand file tree Collapse file tree 2 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ import {
2222 nextTick ,
2323 onMounted ,
2424 openBlock ,
25+ reactive ,
2526 ref ,
2627 renderSlot ,
2728 useCssVars ,
@@ -31,7 +32,7 @@ import {
3132 withDirectives ,
3233} from '@vue/runtime-dom'
3334import { type SSRContext , renderToString } from '@vue/server-renderer'
34- import { PatchFlags } from '@vue/shared'
35+ import { PatchFlags , normalizeStyle } from '@vue/shared'
3536import { vShowOriginalDisplay } from '../../runtime-dom/src/directives/vShow'
3637import { expect } from 'vitest'
3738
@@ -1196,6 +1197,38 @@ describe('SSR hydration', () => {
11961197 expect ( text . nodeType ) . toBe ( 3 )
11971198 } )
11981199
1200+ // #11372
1201+ test ( 'object style value tracking in prod' , async ( ) => {
1202+ __DEV__ = false
1203+ try {
1204+ const style = reactive ( { color : 'red' } )
1205+ const Comp = {
1206+ render ( this : any ) {
1207+ return (
1208+ openBlock ( ) ,
1209+ createElementBlock (
1210+ 'div' ,
1211+ {
1212+ style : normalizeStyle ( style ) ,
1213+ } ,
1214+ null ,
1215+ 4 /* STYLE */ ,
1216+ )
1217+ )
1218+ } ,
1219+ }
1220+ const { container } = mountWithHydration (
1221+ `<div style="color: red;"></div>` ,
1222+ ( ) => h ( Comp ) ,
1223+ )
1224+ style . color = 'green'
1225+ await nextTick ( )
1226+ expect ( container . innerHTML ) . toBe ( `<div style="color: green;"></div>` )
1227+ } finally {
1228+ __DEV__ = true
1229+ }
1230+ } )
1231+
11991232 test ( 'app.unmount()' , async ( ) => {
12001233 const container = document . createElement ( 'DIV' )
12011234 container . innerHTML = '<button></button>'
Original file line number Diff line number Diff line change @@ -39,6 +39,7 @@ import {
3939} from './components/Suspense'
4040import type { TeleportImpl , TeleportVNode } from './components/Teleport'
4141import { isAsyncWrapper } from './apiAsyncComponent'
42+ import { isReactive } from '@vue/reactivity'
4243
4344export type RootHydrateFunction = (
4445 vnode : VNode < Node , Element > ,
@@ -487,6 +488,11 @@ export function createHydrationFunctions(
487488 undefined ,
488489 parentComponent ,
489490 )
491+ } else if ( patchFlag & PatchFlags . STYLE && isReactive ( props . style ) ) {
492+ // #11372: object style values are iterated during patch instead of
493+ // render/normalization phase, but style patch is skipped during
494+ // hydration, so we need to force iterate the object to track deps
495+ for ( const key in props . style ) props . style [ key ]
490496 }
491497 }
492498
You can’t perform that action at this time.
0 commit comments