diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index a1fb8cde33f..45093550bce 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -21,6 +21,7 @@ import {
h,
nextTick,
onMounted,
+ onServerPrefetch,
openBlock,
reactive,
ref,
@@ -518,6 +519,45 @@ describe('SSR hydration', () => {
)
})
+ test('with data-allow-mismatch component when using onServerPrefetch', async () => {
+ const Comp = {
+ template: `
+
Comp2
+ `,
+ }
+ let foo: any
+ const App = {
+ setup() {
+ const flag = ref(true)
+ foo = () => {
+ flag.value = false
+ }
+ onServerPrefetch(() => (flag.value = false))
+ return { flag }
+ },
+ components: {
+ Comp,
+ },
+ template: `
+
+
+
+ `,
+ }
+ // hydrate
+ const container = document.createElement('div')
+ container.innerHTML = await renderToString(h(App))
+ createSSRApp(App).mount(container)
+ expect(container.innerHTML).toBe(
+ 'Comp2
',
+ )
+ foo()
+ await nextTick()
+ expect(container.innerHTML).toBe(
+ '',
+ )
+ })
+
test('Teleport unmount (full integration)', async () => {
const Comp1 = {
template: `
diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts
index c49db529c38..41ae64cd19e 100644
--- a/packages/runtime-core/src/hydration.ts
+++ b/packages/runtime-core/src/hydration.ts
@@ -41,6 +41,7 @@ import {
import type { TeleportImpl, TeleportVNode } from './components/Teleport'
import { isAsyncWrapper } from './apiAsyncComponent'
import { isReactive } from '@vue/reactivity'
+import { updateHOCHostEl } from './componentRenderUtils'
export type RootHydrateFunction = (
vnode: VNode,
@@ -716,6 +717,11 @@ export function createHydrationFunctions(
getContainerType(container),
slotScopeIds,
)
+ // the component vnode's el should be updated when a mismatch occurs.
+ if (parentComponent) {
+ parentComponent.vnode.el = vnode.el
+ updateHOCHostEl(parentComponent, vnode.el)
+ }
return next
}