diff --git a/packages/runtime-vapor/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-vapor/__tests__/helpers/useCssVars.spec.ts index 6ea2d87c2bf..ea8ce0a2b57 100644 --- a/packages/runtime-vapor/__tests__/helpers/useCssVars.spec.ts +++ b/packages/runtime-vapor/__tests__/helpers/useCssVars.spec.ts @@ -297,6 +297,68 @@ describe('useVaporCssVars', () => { expect(host.children[0].outerHTML.includes('data-v-owner')).toBe(true) }) + test('with teleport and nested component', async () => { + const state = reactive({ color: 'red' }) + const target = document.createElement('div') + document.body.appendChild(target) + + const value = ref(true) + const Child = defineVaporComponent({ + setup(_, { slots }) { + return slots.default!() + }, + }) + + const Comp = defineVaporComponent({ + setup() { + return createComponent(Child, null, { + default: () => { + return createComponent(Child, null, { + default: () => { + return createIf( + () => value.value, + () => { + return template('
')() + }, + () => { + return template('')() + }, + ) + }, + }) + }, + }) + }, + }) + + define({ + setup() { + useVaporCssVars(() => state) + const n1 = createComponent( + VaporTeleport, + { to: () => target }, + { + default: () => createComponent(Comp), + }, + ) + return n1 + }, + }).render() + + await nextTick() + let el = target.children[0] as HTMLElement + expect(el.tagName).toBe('DIV') + expect(el.outerHTML.includes('data-v-owner')).toBe(true) + expect(el.style.getPropertyValue(`--color`)).toBe('red') + + value.value = false + await nextTick() + el = target.children[0] as HTMLElement + expect(el.tagName).toBe('SPAN') + expect(el.outerHTML.includes('data-v-owner')).toBe(true) + expect(el.style.getPropertyValue(`--color`)).toBe('red') + }) + test('with string style', async () => { const state = reactive({ color: 'red' }) const root = document.createElement('div') diff --git a/packages/runtime-vapor/src/components/Teleport.ts b/packages/runtime-vapor/src/components/Teleport.ts index 1fadf8ffc20..0e5b26ca172 100644 --- a/packages/runtime-vapor/src/components/Teleport.ts +++ b/packages/runtime-vapor/src/components/Teleport.ts @@ -107,24 +107,12 @@ export class TeleportFragment extends VaporFragment { this.rawSlots!.default && (this.rawSlots!.default as BlockFn)(), ) }) - const nodes = this.nodes - // register updateCssVars to root fragments's update hooks so that + + // register updateCssVars to nested fragments's update hooks so that // it will be called when root fragment changed if (this.parentComponent && this.parentComponent.ut) { - if (isFragment(nodes)) { - ;(nodes.onUpdated || (nodes.onUpdated = [])).push(() => - updateCssVars(this), - ) - } else if (isArray(nodes)) { - nodes.forEach(node => { - if (isFragment(node)) { - ;(node.onUpdated || (node.onUpdated = [])).push(() => - updateCssVars(this), - ) - } - }) - } + this.registerUpdateCssVars(nodes) } if (__DEV__) { @@ -138,6 +126,19 @@ export class TeleportFragment extends VaporFragment { } } + private registerUpdateCssVars(block: Block) { + if (isFragment(block)) { + ;(block.onUpdated || (block.onUpdated = [])).push(() => + updateCssVars(this), + ) + this.registerUpdateCssVars(block.nodes) + } else if (isVaporComponent(block)) { + this.registerUpdateCssVars(block.block) + } else if (isArray(block)) { + block.forEach(node => this.registerUpdateCssVars(node)) + } + } + private handleChildrenUpdate(children: Block): void { // not mounted yet if (!this.parent || isHydrating) {