fix(runtime-dom): set css vars before user onMounted hooks

close #11533
This commit is contained in:
Evan You 2024-11-14 15:49:39 +08:00
parent 99009eee0e
commit 2d5c5e25e9
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
2 changed files with 26 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import {
defineCustomElement, defineCustomElement,
h, h,
nextTick, nextTick,
onMounted,
reactive, reactive,
ref, ref,
render, render,
@ -405,4 +406,25 @@ describe('useCssVars', () => {
`<css-vars-ce style="--color: red;"></css-vars-ce>`, `<css-vars-ce style="--color: red;"></css-vars-ce>`,
) )
}) })
test('should set vars before child component onMount hook', () => {
const state = reactive({ color: 'red' })
const root = document.createElement('div')
let colorInOnMount
const App = {
setup() {
useCssVars(() => state)
onMounted(() => {
colorInOnMount = (
root.children[0] as HTMLElement
).style.getPropertyValue(`--color`)
})
return () => h('div')
},
}
render(h(App), root)
expect(colorInOnMount).toBe(`red`)
})
}) })

View File

@ -3,13 +3,12 @@ import {
Static, Static,
type VNode, type VNode,
getCurrentInstance, getCurrentInstance,
onBeforeMount,
onMounted, onMounted,
onUnmounted, onUnmounted,
warn, warn,
watchPostEffect, watch,
} from '@vue/runtime-core' } from '@vue/runtime-core'
import { ShapeFlags } from '@vue/shared' import { NOOP, ShapeFlags } from '@vue/shared'
export const CSS_VAR_TEXT: unique symbol = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '') export const CSS_VAR_TEXT: unique symbol = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '')
/** /**
@ -48,11 +47,9 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>): void {
updateTeleports(vars) updateTeleports(vars)
} }
onBeforeMount(() => {
watchPostEffect(setVars)
})
onMounted(() => { onMounted(() => {
// run setVars synchronously here, but run as post-effect on changes
watch(setVars, NOOP, { flush: 'post' })
const ob = new MutationObserver(setVars) const ob = new MutationObserver(setVars)
ob.observe(instance.subTree.el!.parentNode, { childList: true }) ob.observe(instance.subTree.el!.parentNode, { childList: true })
onUnmounted(() => ob.disconnect()) onUnmounted(() => ob.disconnect())