From 2d5c5e25e9b7a56e883674fb434135ac514429b5 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Nov 2024 15:49:39 +0800 Subject: [PATCH] fix(runtime-dom): set css vars before user onMounted hooks close #11533 --- .../__tests__/helpers/useCssVars.spec.ts | 22 +++++++++++++++++++ .../runtime-dom/src/helpers/useCssVars.ts | 11 ++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index c4df0873140..acba3315862 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 e57705304bf..6331208c5c0 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())