Skip to content

Commit

Permalink
fix(ssr): fix hydration error when disabled teleport is component root
Browse files Browse the repository at this point in the history
  • Loading branch information
KaelWD committed Jun 21, 2022
1 parent 25f7a16 commit 9d8c15e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 10 deletions.
36 changes: 33 additions & 3 deletions packages/runtime-core/__tests__/hydration.spec.ts
Expand Up @@ -418,17 +418,47 @@ describe('SSR hydration', () => {
expect(nextVNode.el).toBe(container.firstChild?.lastChild)
})

test('Teleport (nested)', () => {
test('Teleport (as component root, disabled)', () => {
const teleportContainer = document.createElement('div')
teleportContainer.id = 'teleport5'
document.body.appendChild(teleportContainer)

const wrapper = {
render() {
return h(Teleport, { to: '#teleport5', disabled: true }, [
h('div', ['hello'])
])
}
}

const { vnode, container } = mountWithHydration(
'<div><!--teleport start--><div>hello</div><!--teleport end--><div></div></div>',
() => h('div', [h(wrapper), h('div')])
)
expect(vnode.el).toBe(container.firstChild)
// component el
const wrapperVNode = (vnode as any).children[0]
const tpStart = container.firstChild?.firstChild
const tpEnd = tpStart?.nextSibling?.nextSibling
expect(wrapperVNode.el).toBe(tpStart)
expect(wrapperVNode.component.subTree.el).toBe(tpStart)
expect(wrapperVNode.component.subTree.anchor).toBe(tpEnd)
// next node hydrate properly
const nextVNode = (vnode as any).children[1]
expect(nextVNode.el).toBe(container.firstChild?.lastChild)
})

test('Teleport (nested)', () => {
const teleportContainer = document.createElement('div')
teleportContainer.id = 'teleport6'
teleportContainer.innerHTML = `<div><!--teleport start--><!--teleport end--></div><!--teleport anchor--><div>child</div><!--teleport anchor-->`
document.body.appendChild(teleportContainer)

const { vnode, container } = mountWithHydration(
'<!--teleport start--><!--teleport end-->',
() =>
h(Teleport, { to: '#teleport5' }, [
h('div', [h(Teleport, { to: '#teleport5' }, [h('div', 'child')])])
h(Teleport, { to: '#teleport6' }, [
h('div', [h(Teleport, { to: '#teleport6' }, [h('div', 'child')])])
])
)

Expand Down
20 changes: 13 additions & 7 deletions packages/runtime-core/src/hydration.ts
Expand Up @@ -227,13 +227,19 @@ export function createHydrationFunctions(
? locateClosingAsyncAnchor(node)
: nextSibling(node)

// #4293 teleport as component root
if (
nextNode &&
isComment(nextNode) &&
nextNode.data === 'teleport end'
) {
nextNode = nextSibling(nextNode)
// #6152 teleport as component root
if (isComment(node) && node.data === 'teleport start') {
while (
nextNode && !(
isComment(nextNode) &&
nextNode.data === 'teleport end'
)
) {
nextNode = nextSibling(nextNode)
}
if (nextNode) {
nextNode = nextSibling(nextNode)
}
}

// #3787
Expand Down

0 comments on commit 9d8c15e

Please sign in to comment.