Skip to content

Commit 9bb5046

Browse files
fix(teleport): handle css var update on nested fragment (#14284)
Co-authored-by: daiwei <[email protected]>
1 parent d88a9a9 commit 9bb5046

File tree

2 files changed

+78
-15
lines changed

2 files changed

+78
-15
lines changed

packages/runtime-vapor/__tests__/helpers/useCssVars.spec.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,68 @@ describe('useVaporCssVars', () => {
297297
expect(host.children[0].outerHTML.includes('data-v-owner')).toBe(true)
298298
})
299299

300+
test('with teleport and nested component', async () => {
301+
const state = reactive({ color: 'red' })
302+
const target = document.createElement('div')
303+
document.body.appendChild(target)
304+
305+
const value = ref(true)
306+
const Child = defineVaporComponent({
307+
setup(_, { slots }) {
308+
return slots.default!()
309+
},
310+
})
311+
312+
const Comp = defineVaporComponent({
313+
setup() {
314+
return createComponent(Child, null, {
315+
default: () => {
316+
return createComponent(Child, null, {
317+
default: () => {
318+
return createIf(
319+
() => value.value,
320+
() => {
321+
return template('<div></div>')()
322+
},
323+
() => {
324+
return template('<span></span>')()
325+
},
326+
)
327+
},
328+
})
329+
},
330+
})
331+
},
332+
})
333+
334+
define({
335+
setup() {
336+
useVaporCssVars(() => state)
337+
const n1 = createComponent(
338+
VaporTeleport,
339+
{ to: () => target },
340+
{
341+
default: () => createComponent(Comp),
342+
},
343+
)
344+
return n1
345+
},
346+
}).render()
347+
348+
await nextTick()
349+
let el = target.children[0] as HTMLElement
350+
expect(el.tagName).toBe('DIV')
351+
expect(el.outerHTML.includes('data-v-owner')).toBe(true)
352+
expect(el.style.getPropertyValue(`--color`)).toBe('red')
353+
354+
value.value = false
355+
await nextTick()
356+
el = target.children[0] as HTMLElement
357+
expect(el.tagName).toBe('SPAN')
358+
expect(el.outerHTML.includes('data-v-owner')).toBe(true)
359+
expect(el.style.getPropertyValue(`--color`)).toBe('red')
360+
})
361+
300362
test('with string style', async () => {
301363
const state = reactive({ color: 'red' })
302364
const root = document.createElement('div')

packages/runtime-vapor/src/components/Teleport.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,24 +107,12 @@ export class TeleportFragment extends VaporFragment {
107107
this.rawSlots!.default && (this.rawSlots!.default as BlockFn)(),
108108
)
109109
})
110-
111110
const nodes = this.nodes
112-
// register updateCssVars to root fragments's update hooks so that
111+
112+
// register updateCssVars to nested fragments's update hooks so that
113113
// it will be called when root fragment changed
114114
if (this.parentComponent && this.parentComponent.ut) {
115-
if (isFragment(nodes)) {
116-
;(nodes.onUpdated || (nodes.onUpdated = [])).push(() =>
117-
updateCssVars(this),
118-
)
119-
} else if (isArray(nodes)) {
120-
nodes.forEach(node => {
121-
if (isFragment(node)) {
122-
;(node.onUpdated || (node.onUpdated = [])).push(() =>
123-
updateCssVars(this),
124-
)
125-
}
126-
})
127-
}
115+
this.registerUpdateCssVars(nodes)
128116
}
129117

130118
if (__DEV__) {
@@ -138,6 +126,19 @@ export class TeleportFragment extends VaporFragment {
138126
}
139127
}
140128

129+
private registerUpdateCssVars(block: Block) {
130+
if (isFragment(block)) {
131+
;(block.onUpdated || (block.onUpdated = [])).push(() =>
132+
updateCssVars(this),
133+
)
134+
this.registerUpdateCssVars(block.nodes)
135+
} else if (isVaporComponent(block)) {
136+
this.registerUpdateCssVars(block.block)
137+
} else if (isArray(block)) {
138+
block.forEach(node => this.registerUpdateCssVars(node))
139+
}
140+
}
141+
141142
private handleChildrenUpdate(children: Block): void {
142143
// not mounted yet
143144
if (!this.parent || isHydrating) {

0 commit comments

Comments
 (0)