diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index 6ae9caf8e..ea1d626f7 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -22,6 +22,7 @@ import { nextTick, onMounted, openBlock, + reactive, ref, renderSlot, useCssVars, @@ -31,7 +32,7 @@ import { withDirectives, } from '@vue/runtime-dom' import { type SSRContext, renderToString } from '@vue/server-renderer' -import { PatchFlags } from '@vue/shared' +import { PatchFlags, normalizeStyle } from '@vue/shared' import { vShowOriginalDisplay } from '../../runtime-dom/src/directives/vShow' import { expect } from 'vitest' @@ -1196,6 +1197,38 @@ describe('SSR hydration', () => { expect(text.nodeType).toBe(3) }) + // #11372 + test('object style value tracking in prod', async () => { + __DEV__ = false + try { + const style = reactive({ color: 'red' }) + const Comp = { + render(this: any) { + return ( + openBlock(), + createElementBlock( + 'div', + { + style: normalizeStyle(style), + }, + null, + 4 /* STYLE */, + ) + ) + }, + } + const { container } = mountWithHydration( + `
`, + () => h(Comp), + ) + style.color = 'green' + await nextTick() + expect(container.innerHTML).toBe(``) + } finally { + __DEV__ = true + } + }) + test('app.unmount()', async () => { const container = document.createElement('DIV') container.innerHTML = '' diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 20ff37cdf..fe267f4fe 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -39,6 +39,7 @@ import { } from './components/Suspense' import type { TeleportImpl, TeleportVNode } from './components/Teleport' import { isAsyncWrapper } from './apiAsyncComponent' +import { isReactive } from '@vue/reactivity' export type RootHydrateFunction = ( vnode: VNode