Skip to content
24 changes: 24 additions & 0 deletions packages/runtime-core/__tests__/hydration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1973,5 +1973,29 @@ describe('SSR hydration', () => {
app.mount(container)
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
})

test('with disabled teleport + undefined target', async () => {
const container = document.createElement('div')
const isOpen = ref(false)
const App = {
setup() {
return { isOpen }
},
template: `
<Teleport :to="undefined" :disabled="true">
<div v-if="isOpen">
Menu is open...
</div>
</Teleport>`,
}
container.innerHTML = await renderToString(h(App))
const app = createSSRApp(App)
app.mount(container)
isOpen.value = true
await nextTick()
expect(container.innerHTML).toBe(
`<!--teleport start--><div> Menu is open... </div><!--teleport end-->`,
)
})
})
})
36 changes: 27 additions & 9 deletions packages/runtime-core/src/components/Teleport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,25 @@ function hydrateTeleport(
optimized: boolean,
) => Node | null,
): Node | null {
function hydrateDisabledTeleport(
node: Node,
vnode: VNode,
targetStart: Node | null,
targetAnchor: Node | null,
) {
vnode.anchor = hydrateChildren(
nextSibling(node),
vnode,
parentNode(node)!,
parentComponent,
parentSuspense,
slotScopeIds,
optimized,
)
vnode.targetStart = targetStart
vnode.targetAnchor = targetAnchor
}

const target = (vnode.target = resolveTarget<Element>(
vnode.props,
querySelector,
Expand All @@ -372,17 +391,12 @@ function hydrateTeleport(
(target as TeleportTargetElement)._lpa || target.firstChild
if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
if (isTeleportDisabled(vnode.props)) {
vnode.anchor = hydrateChildren(
nextSibling(node),
hydrateDisabledTeleport(
node,
vnode,
parentNode(node)!,
parentComponent,
parentSuspense,
slotScopeIds,
optimized,
targetNode,
targetNode && nextSibling(targetNode),
)
vnode.targetStart = targetNode
vnode.targetAnchor = targetNode && nextSibling(targetNode)
} else {
vnode.anchor = nextSibling(node)

Expand Down Expand Up @@ -424,6 +438,10 @@ function hydrateTeleport(
}
}
updateCssVars(vnode)
} else if (isTeleportDisabled(vnode.props)) {
if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
hydrateDisabledTeleport(node, vnode, node, nextSibling(node))
}
}
return vnode.anchor && nextSibling(vnode.anchor as Node)
}
Expand Down