File tree 2 files changed +40
-1
lines changed
2 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ import {
22
22
nextTick ,
23
23
onMounted ,
24
24
openBlock ,
25
+ reactive ,
25
26
ref ,
26
27
renderSlot ,
27
28
useCssVars ,
@@ -31,7 +32,7 @@ import {
31
32
withDirectives ,
32
33
} from '@vue/runtime-dom'
33
34
import { type SSRContext , renderToString } from '@vue/server-renderer'
34
- import { PatchFlags } from '@vue/shared'
35
+ import { PatchFlags , normalizeStyle } from '@vue/shared'
35
36
import { vShowOriginalDisplay } from '../../runtime-dom/src/directives/vShow'
36
37
import { expect } from 'vitest'
37
38
@@ -1196,6 +1197,38 @@ describe('SSR hydration', () => {
1196
1197
expect ( text . nodeType ) . toBe ( 3 )
1197
1198
} )
1198
1199
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
+
1199
1232
test ( 'app.unmount()' , async ( ) => {
1200
1233
const container = document . createElement ( 'DIV' )
1201
1234
container . innerHTML = '<button></button>'
Original file line number Diff line number Diff line change @@ -39,6 +39,7 @@ import {
39
39
} from './components/Suspense'
40
40
import type { TeleportImpl , TeleportVNode } from './components/Teleport'
41
41
import { isAsyncWrapper } from './apiAsyncComponent'
42
+ import { isReactive } from '@vue/reactivity'
42
43
43
44
export type RootHydrateFunction = (
44
45
vnode : VNode < Node , Element > ,
@@ -487,6 +488,11 @@ export function createHydrationFunctions(
487
488
undefined ,
488
489
parentComponent ,
489
490
)
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 ]
490
496
}
491
497
}
492
498
You can’t perform that action at this time.
0 commit comments