From: 白雾三语 <32354856+baiwusanyu-c@users.noreply.github.com>
Date: Thu, 25 Jun 2026 08:17:46 +0000 (+0800)
Subject: fix(hydration): force patch dynamic props when hydrating (#9083)
X-Git-Tag: v3.5.39~8
X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=024cf06daa33db4660431f20aa050acb99cff07f;p=thirdparty%2Fvuejs%2Fcore.git
fix(hydration): force patch dynamic props when hydrating (#9083)
close: #9033
---
diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index 2fe6491040..77ab520a8b 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -2673,5 +2673,52 @@ describe('SSR hydration', () => {
)
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
})
+
+ // #9033
+ test('force patch dynamic props when hydrating', () => {
+ __DEV__ = false
+ try {
+ const { container } = mountWithHydration(
+ `
`,
+ () => (
+ openBlock(),
+ createElementBlock('div', null, [
+ createElementVNode(
+ 'div',
+ { innerHTML: 'client' },
+ null,
+ PatchFlags.PROPS,
+ ['innerHTML'],
+ ),
+ ])
+ ),
+ )
+ expect(container.innerHTML).toBe(``)
+ } finally {
+ __DEV__ = true
+ }
+ })
+
+ test('only patches declared dynamic props when hydrating', () => {
+ const { container } = mountWithHydration(
+ ``,
+ () =>
+ createVNode(
+ 'div',
+ {
+ 'data-allow-mismatch': 'attribute',
+ id: 'client',
+ value: 'client',
+ },
+ null,
+ PatchFlags.PROPS,
+ ['id'],
+ ),
+ )
+ const el = container.firstChild as Element
+
+ expect(el.getAttribute('id')).toBe('client')
+ expect(el.getAttribute('value')).toBe('server')
+ })
})
})
diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts
index 464db7519b..cecb934970 100644
--- a/packages/runtime-core/src/hydration.ts
+++ b/packages/runtime-core/src/hydration.ts
@@ -374,14 +374,30 @@ export function createHydrationFunctions(
optimized: boolean,
) => {
optimized = optimized || !!vnode.dynamicChildren
- const { type, props, patchFlag, shapeFlag, dirs, transition } = vnode
+ const {
+ type,
+ dynamicProps,
+ props,
+ patchFlag,
+ shapeFlag,
+ dirs,
+ transition,
+ } = vnode
// #4006 for form elements with non-string v-model value bindings
// e.g.