Skip to content

Commit 3354646

Browse files
pikaxyyx990803
authored andcommitted
fix(ssr): Using teleport disabled causes mismatch
1 parent a8f6638 commit 3354646

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,5 +1083,29 @@ describe('SSR hydration', () => {
10831083
expect(teleportContainer.innerHTML).toBe(`<span>value</span>`)
10841084
expect(`Hydration children mismatch`).toHaveBeenWarned()
10851085
})
1086+
// #6152
1087+
test('Teleport is disabled', () => {
1088+
const { container } = mountWithHydration(
1089+
'<!--[--><div>Parent fragment</div><!--teleport start--><div>Teleport content</div><!--teleport end--><!--]-->',
1090+
() => [
1091+
h('div', 'Parent fragment'),
1092+
h(
1093+
defineComponent(
1094+
() => () =>
1095+
h(Teleport, { to: 'body', disabled: true }, [
1096+
h('div', 'Teleport content')
1097+
])
1098+
)
1099+
)
1100+
]
1101+
)
1102+
expect(document.body.innerHTML).toBe('')
1103+
expect(container.innerHTML).toBe(
1104+
'<!--[--><div>Parent fragment</div><!--teleport start--><div>Teleport content</div><!--teleport end--><!--]-->'
1105+
)
1106+
expect(
1107+
`Hydration completed but contains mismatches.`
1108+
).not.toHaveBeenWarned()
1109+
})
10861110
})
10871111
})

packages/runtime-core/src/hydration.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,17 +232,11 @@ export function createHydrationFunctions(
232232
// instead, we do a lookahead to find the end anchor node.
233233
nextNode = isFragmentStart
234234
? locateClosingAsyncAnchor(node)
235+
: // #4293 #6152 if teleport start look ahead for teleport end.
236+
isComment(node) && node.data === 'teleport start'
237+
? locateClosingTeleportAnchor(node)
235238
: nextSibling(node)
236239

237-
// #4293 teleport as component root
238-
if (
239-
nextNode &&
240-
isComment(nextNode) &&
241-
nextNode.data === 'teleport end'
242-
) {
243-
nextNode = nextSibling(nextNode)
244-
}
245-
246240
// #3787
247241
// if component is async, it may get moved / unmounted before its
248242
// inner component is loaded, so we need to give it a placeholder
@@ -579,5 +573,23 @@ export function createHydrationFunctions(
579573
return node
580574
}
581575

576+
const locateClosingTeleportAnchor = (node: Node | null): Node | null => {
577+
let match = 0
578+
while (node) {
579+
node = nextSibling(node)
580+
if (node && isComment(node)) {
581+
if (node.data === 'teleport start') match++
582+
if (node.data === 'teleport end') {
583+
if (match === 0) {
584+
return nextSibling(node)
585+
} else {
586+
match--
587+
}
588+
}
589+
}
590+
}
591+
return node
592+
}
593+
582594
return [hydrate, hydrateNode] as const
583595
}

0 commit comments

Comments
 (0)