mirror of https://github.com/vuejs/core.git
fix(runtime-dom): set css vars on update to handle child forcing reflow in onMount (#11561)
This commit is contained in:
parent
2d5c5e25e9
commit
c4312f9c71
|
@ -385,6 +385,44 @@ describe('useCssVars', () => {
|
|||
}
|
||||
})
|
||||
|
||||
test('with delay mount child', async () => {
|
||||
const state = reactive({ color: 'red' })
|
||||
const value = ref(false)
|
||||
const root = document.createElement('div')
|
||||
|
||||
const Child = {
|
||||
setup() {
|
||||
onMounted(() => {
|
||||
const childEl = root.children[0]
|
||||
expect(getComputedStyle(childEl!).getPropertyValue(`--color`)).toBe(
|
||||
`red`,
|
||||
)
|
||||
})
|
||||
return () => h('div', { id: 'childId' })
|
||||
},
|
||||
}
|
||||
const App = {
|
||||
setup() {
|
||||
useCssVars(() => state)
|
||||
return () => (value.value ? h(Child) : [h('span')])
|
||||
},
|
||||
}
|
||||
|
||||
render(h(App), root)
|
||||
await nextTick()
|
||||
// css vars use with fallback tree
|
||||
for (const c of [].slice.call(root.children as any)) {
|
||||
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
|
||||
}
|
||||
|
||||
// mount child
|
||||
value.value = true
|
||||
await nextTick()
|
||||
for (const c of [].slice.call(root.children as any)) {
|
||||
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
|
||||
}
|
||||
})
|
||||
|
||||
// #8826
|
||||
test('with custom element', async () => {
|
||||
const state = reactive({ color: 'red' })
|
||||
|
|
|
@ -3,8 +3,10 @@ import {
|
|||
Static,
|
||||
type VNode,
|
||||
getCurrentInstance,
|
||||
onBeforeUpdate,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
queuePostFlushCb,
|
||||
warn,
|
||||
watch,
|
||||
} from '@vue/runtime-core'
|
||||
|
@ -47,6 +49,12 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>): void {
|
|||
updateTeleports(vars)
|
||||
}
|
||||
|
||||
// handle cases where child component root is affected
|
||||
// and triggers reflow in onMounted
|
||||
onBeforeUpdate(() => {
|
||||
queuePostFlushCb(setVars)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// run setVars synchronously here, but run as post-effect on changes
|
||||
watch(setVars, NOOP, { flush: 'post' })
|
||||
|
|
Loading…
Reference in New Issue