This commit is contained in:
linzhe 2025-05-05 20:38:28 +00:00 committed by GitHub
commit c0ef40aaf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 10 deletions

View File

@ -2185,6 +2185,30 @@ describe('SSR hydration', () => {
expect(`Hydration style mismatch`).not.toHaveBeenWarned() 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-->`,
)
})
test('escape css var name', () => { test('escape css var name', () => {
const container = document.createElement('div') const container = document.createElement('div')
container.innerHTML = `<div style="padding: 4px;--foo\\.bar:red;"></div>` container.innerHTML = `<div style="padding: 4px;--foo\\.bar:red;"></div>`

View File

@ -406,29 +406,43 @@ function hydrateTeleport(
optimized: boolean, optimized: boolean,
) => Node | null, ) => Node | null,
): 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>( const target = (vnode.target = resolveTarget<Element>(
vnode.props, vnode.props,
querySelector, querySelector,
)) ))
const disabled = isTeleportDisabled(vnode.props)
if (target) { if (target) {
const disabled = isTeleportDisabled(vnode.props)
// if multiple teleports rendered to the same target element, we need to // 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 // pick up from where the last teleport finished instead of the first node
const targetNode = const targetNode =
(target as TeleportTargetElement)._lpa || target.firstChild (target as TeleportTargetElement)._lpa || target.firstChild
if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) { if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
if (disabled) { if (disabled) {
vnode.anchor = hydrateChildren( hydrateDisabledTeleport(
nextSibling(node), node,
vnode, vnode,
parentNode(node)!, targetNode,
parentComponent, targetNode && nextSibling(targetNode),
parentSuspense,
slotScopeIds,
optimized,
) )
vnode.targetStart = targetNode
vnode.targetAnchor = targetNode && nextSibling(targetNode)
} else { } else {
vnode.anchor = nextSibling(node) vnode.anchor = nextSibling(node)
@ -470,6 +484,10 @@ function hydrateTeleport(
} }
} }
updateCssVars(vnode, disabled) 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) return vnode.anchor && nextSibling(vnode.anchor as Node)
} }