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 }