diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index 56011d063..2cd306817 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -2185,6 +2185,30 @@ describe('SSR hydration', () => {
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: `
+
+
+ Menu is open...
+
+ `,
+ }
+ container.innerHTML = await renderToString(h(App))
+ const app = createSSRApp(App)
+ app.mount(container)
+ isOpen.value = true
+ await nextTick()
+ expect(container.innerHTML).toBe(
+ `
Menu is open...
`,
+ )
+ })
+
test('escape css var name', () => {
const container = document.createElement('div')
container.innerHTML = ``
diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts
index fc2ee4c08..21e512618 100644
--- a/packages/runtime-core/src/components/Teleport.ts
+++ b/packages/runtime-core/src/components/Teleport.ts
@@ -406,29 +406,43 @@ 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(
vnode.props,
querySelector,
))
+ const disabled = isTeleportDisabled(vnode.props)
if (target) {
- const disabled = isTeleportDisabled(vnode.props)
// if multiple teleports rendered to the same target element, we need to
// pick up from where the last teleport finished instead of the first node
const targetNode =
(target as TeleportTargetElement)._lpa || target.firstChild
if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
if (disabled) {
- 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)
@@ -470,6 +484,10 @@ function hydrateTeleport(
}
}
updateCssVars(vnode, disabled)
+ } else if (disabled) {
+ if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+ hydrateDisabledTeleport(node, vnode, node, nextSibling(node))
+ }
}
return vnode.anchor && nextSibling(vnode.anchor as Node)
}