Skip to content

Commit c4312f9

Browse files
authoredNov 14, 2024··
fix(runtime-dom): set css vars on update to handle child forcing reflow in onMount (#11561)
1 parent 2d5c5e2 commit c4312f9

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed
 

‎packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts

+38
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,44 @@ describe('useCssVars', () => {
385385
}
386386
})
387387

388+
test('with delay mount child', async () => {
389+
const state = reactive({ color: 'red' })
390+
const value = ref(false)
391+
const root = document.createElement('div')
392+
393+
const Child = {
394+
setup() {
395+
onMounted(() => {
396+
const childEl = root.children[0]
397+
expect(getComputedStyle(childEl!).getPropertyValue(`--color`)).toBe(
398+
`red`,
399+
)
400+
})
401+
return () => h('div', { id: 'childId' })
402+
},
403+
}
404+
const App = {
405+
setup() {
406+
useCssVars(() => state)
407+
return () => (value.value ? h(Child) : [h('span')])
408+
},
409+
}
410+
411+
render(h(App), root)
412+
await nextTick()
413+
// css vars use with fallback tree
414+
for (const c of [].slice.call(root.children as any)) {
415+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
416+
}
417+
418+
// mount child
419+
value.value = true
420+
await nextTick()
421+
for (const c of [].slice.call(root.children as any)) {
422+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
423+
}
424+
})
425+
388426
// #8826
389427
test('with custom element', async () => {
390428
const state = reactive({ color: 'red' })

‎packages/runtime-dom/src/helpers/useCssVars.ts

+8
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import {
33
Static,
44
type VNode,
55
getCurrentInstance,
6+
onBeforeUpdate,
67
onMounted,
78
onUnmounted,
9+
queuePostFlushCb,
810
warn,
911
watch,
1012
} from '@vue/runtime-core'
@@ -47,6 +49,12 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>): void {
4749
updateTeleports(vars)
4850
}
4951

52+
// handle cases where child component root is affected
53+
// and triggers reflow in onMounted
54+
onBeforeUpdate(() => {
55+
queuePostFlushCb(setVars)
56+
})
57+
5058
onMounted(() => {
5159
// run setVars synchronously here, but run as post-effect on changes
5260
watch(setVars, NOOP, { flush: 'post' })

0 commit comments

Comments
 (0)
Please sign in to comment.