diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts
index c4df08731..acba33158 100644
--- a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts
+++ b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts
@@ -7,6 +7,7 @@ import {
defineCustomElement,
h,
nextTick,
+ onMounted,
reactive,
ref,
render,
@@ -405,4 +406,25 @@ describe('useCssVars', () => {
``,
)
})
+
+ 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`)
+ })
})
diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts
index e57705304..6331208c5 100644
--- a/packages/runtime-dom/src/helpers/useCssVars.ts
+++ b/packages/runtime-dom/src/helpers/useCssVars.ts
@@ -3,13 +3,12 @@ import {
Static,
type VNode,
getCurrentInstance,
- onBeforeMount,
onMounted,
onUnmounted,
warn,
- watchPostEffect,
+ watch,
} 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' : '')
/**
@@ -48,11 +47,9 @@ export function useCssVars(getter: (ctx: any) => Record): void {
updateTeleports(vars)
}
- onBeforeMount(() => {
- watchPostEffect(setVars)
- })
-
onMounted(() => {
+ // run setVars synchronously here, but run as post-effect on changes
+ watch(setVars, NOOP, { flush: 'post' })
const ob = new MutationObserver(setVars)
ob.observe(instance.subTree.el!.parentNode, { childList: true })
onUnmounted(() => ob.disconnect())