From 76a8223199c148b79a5c0ea19e235164809760cd Mon Sep 17 00:00:00 2001 From: linzhe <40790268+linzhe141@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:50:36 +0800 Subject: [PATCH] fix(teleport): handle disabled teleport with updateCssVars (#12113) close #12112 --- .../runtime-core/src/components/Teleport.ts | 24 ++++++++++++------- .../__tests__/helpers/useCssVars.spec.ts | 1 + 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index d268322cb12..5def1b2d721 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -147,7 +147,7 @@ export const TeleportImpl = { } if (!disabled) { mount(target, targetAnchor) - updateCssVars(n2) + updateCssVars(n2, false) } } else if (__DEV__ && !disabled) { warn( @@ -160,7 +160,7 @@ export const TeleportImpl = { if (disabled) { mount(container, mainAnchor) - updateCssVars(n2) + updateCssVars(n2, true) } if (isTeleportDeferred(n2.props)) { @@ -267,7 +267,7 @@ export const TeleportImpl = { ) } } - updateCssVars(n2) + updateCssVars(n2, disabled) } }, @@ -389,12 +389,13 @@ function hydrateTeleport( querySelector, )) 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 (isTeleportDisabled(vnode.props)) { + if (disabled) { vnode.anchor = hydrateChildren( nextSibling(node), vnode, @@ -446,7 +447,7 @@ function hydrateTeleport( ) } } - updateCssVars(vnode) + updateCssVars(vnode, disabled) } return vnode.anchor && nextSibling(vnode.anchor as Node) } @@ -462,13 +463,20 @@ export const Teleport = TeleportImpl as unknown as { } } -function updateCssVars(vnode: VNode) { +function updateCssVars(vnode: VNode, isDisabled: boolean) { // presence of .ut method indicates owner component uses css vars. // code path here can assume browser environment. const ctx = vnode.ctx if (ctx && ctx.ut) { - let node = vnode.targetStart - while (node && node !== vnode.targetAnchor) { + let node, anchor + if (isDisabled) { + node = vnode.el + anchor = vnode.anchor + } else { + node = vnode.targetStart + anchor = vnode.targetAnchor + } + while (node && node !== anchor) { if (node.nodeType === 1) node.setAttribute('data-v-owner', ctx.uid) node = node.nextSibling } diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index 06b3e714132..c4df0873140 100644 --- a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts +++ b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts @@ -350,6 +350,7 @@ describe('useCssVars', () => { expect(() => render(h(App), root)).not.toThrow(TypeError) await nextTick() expect(target.children.length).toBe(0) + expect(root.children[0].outerHTML.includes('data-v-owner')).toBe(true) }) test('with string style', async () => {