diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index 3fa0d7e732e..de2d4fcb189 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -1554,5 +1554,21 @@ describe('SSR hydration', () => {
app.mount(container)
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
})
+
+ test('css vars should only be added to expected on component root dom', () => {
+ const container = document.createElement('div')
+ container.innerHTML = `
`
+ const app = createSSRApp({
+ setup() {
+ useCssVars(() => ({
+ foo: 'red',
+ }))
+ return () =>
+ h('div', null, [h('div', { style: { color: 'var(--foo)' } })])
+ },
+ })
+ app.mount(container)
+ expect(`Hydration style mismatch`).not.toHaveBeenWarned()
+ })
})
})
diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts
index 1e9200ce27b..fa61ed96a94 100644
--- a/packages/runtime-core/src/hydration.ts
+++ b/packages/runtime-core/src/hydration.ts
@@ -753,9 +753,11 @@ function propHasMismatch(
}
}
- const cssVars = instance?.getCssVars?.()
- for (const key in cssVars) {
- expectedMap.set(`--${key}`, String(cssVars[key]))
+ if (instance && isInstanceRootEl(instance.subTree, el)) {
+ const cssVars = instance?.getCssVars?.()
+ for (const key in cssVars) {
+ expectedMap.set(`--${key}`, String(cssVars[key]))
+ }
}
if (!isMapEqual(actualMap, expectedMap)) {
@@ -852,3 +854,25 @@ function isMapEqual(a: Map, b: Map): boolean {
}
return true
}
+
+function isInstanceRootEl(vnode: VNode, element: Element): boolean {
+ while (vnode.component) {
+ vnode = vnode.component.subTree
+ }
+
+ if (vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.el) {
+ return element === vnode.el
+ } else if (vnode.type === Fragment) {
+ return (vnode.children as VNode[]).some(c => isInstanceRootEl(c, element))
+ } else if (vnode.type === Static) {
+ let { el, anchor } = vnode
+ while (el) {
+ if (el === element) {
+ return true
+ }
+ if (el === anchor) break
+ el = el.nextSibling
+ }
+ }
+ return false
+}