Skip to content

Commit a20a4cb

Browse files
authoredNov 15, 2024··
fix(hydration): the component vnode's el should be updated when a mismatch occurs. (#12255)
close #12253
1 parent 352bc88 commit a20a4cb

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed
 

‎packages/runtime-core/__tests__/hydration.spec.ts

+40
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
h,
2222
nextTick,
2323
onMounted,
24+
onServerPrefetch,
2425
openBlock,
2526
reactive,
2627
ref,
@@ -518,6 +519,45 @@ describe('SSR hydration', () => {
518519
)
519520
})
520521

522+
test('with data-allow-mismatch component when using onServerPrefetch', async () => {
523+
const Comp = {
524+
template: `
525+
<div>Comp2</div>
526+
`,
527+
}
528+
let foo: any
529+
const App = {
530+
setup() {
531+
const flag = ref(true)
532+
foo = () => {
533+
flag.value = false
534+
}
535+
onServerPrefetch(() => (flag.value = false))
536+
return { flag }
537+
},
538+
components: {
539+
Comp,
540+
},
541+
template: `
542+
<span data-allow-mismatch>
543+
<Comp v-if="flag"></Comp>
544+
</span>
545+
`,
546+
}
547+
// hydrate
548+
const container = document.createElement('div')
549+
container.innerHTML = await renderToString(h(App))
550+
createSSRApp(App).mount(container)
551+
expect(container.innerHTML).toBe(
552+
'<span data-allow-mismatch=""><div>Comp2</div></span>',
553+
)
554+
foo()
555+
await nextTick()
556+
expect(container.innerHTML).toBe(
557+
'<span data-allow-mismatch=""><!--v-if--></span>',
558+
)
559+
})
560+
521561
test('Teleport unmount (full integration)', async () => {
522562
const Comp1 = {
523563
template: `

‎packages/runtime-core/src/hydration.ts

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
import type { TeleportImpl, TeleportVNode } from './components/Teleport'
4242
import { isAsyncWrapper } from './apiAsyncComponent'
4343
import { isReactive } from '@vue/reactivity'
44+
import { updateHOCHostEl } from './componentRenderUtils'
4445

4546
export type RootHydrateFunction = (
4647
vnode: VNode<Node, Element>,
@@ -716,6 +717,11 @@ export function createHydrationFunctions(
716717
getContainerType(container),
717718
slotScopeIds,
718719
)
720+
// the component vnode's el should be updated when a mismatch occurs.
721+
if (parentComponent) {
722+
parentComponent.vnode.el = vnode.el
723+
updateHOCHostEl(parentComponent, vnode.el)
724+
}
719725
return next
720726
}
721727

0 commit comments

Comments
 (0)
Please sign in to comment.