Skip to content

Commit f0b5f7e

Browse files
authoredFeb 6, 2024··
fix(hydration): fix SFC style v-bind hydration mismatch warnings (#10250)
close #10215
1 parent f31d782 commit f0b5f7e

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed
 

‎packages/runtime-core/__tests__/hydration.spec.ts

+16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
onMounted,
2020
ref,
2121
renderSlot,
22+
useCssVars,
2223
vModelCheckbox,
2324
vShow,
2425
withDirectives,
@@ -1538,5 +1539,20 @@ describe('SSR hydration', () => {
15381539
)
15391540
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
15401541
})
1542+
1543+
test('should not warn css v-bind', () => {
1544+
const container = document.createElement('div')
1545+
container.innerHTML = `<div style="--foo:red;color:var(--foo);" />`
1546+
const app = createSSRApp({
1547+
setup() {
1548+
useCssVars(() => ({
1549+
foo: 'red',
1550+
}))
1551+
return () => h('div', { style: { color: 'var(--foo)' } })
1552+
},
1553+
})
1554+
app.mount(container)
1555+
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
1556+
})
15411557
})
15421558
})

‎packages/runtime-core/src/component.ts

+6
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,12 @@ export interface ComponentInternalInstance {
519519
* @internal
520520
*/
521521
ut?: (vars?: Record<string, string>) => void
522+
523+
/**
524+
* dev only. For style v-bind hydration mismatch checks
525+
* @internal
526+
*/
527+
getCssVars?: () => Record<string, string>
522528
}
523529

524530
const emptyAppContext = createAppContext()

‎packages/runtime-core/src/hydration.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,10 @@ export function createHydrationFunctions(
449449
) {
450450
for (const key in props) {
451451
// check hydration mismatch
452-
if (__DEV__ && propHasMismatch(el, key, props[key], vnode)) {
452+
if (
453+
__DEV__ &&
454+
propHasMismatch(el, key, props[key], vnode, parentComponent)
455+
) {
453456
hasMismatch = true
454457
}
455458
if (
@@ -718,6 +721,7 @@ function propHasMismatch(
718721
key: string,
719722
clientValue: any,
720723
vnode: VNode,
724+
instance: ComponentInternalInstance | null,
721725
): boolean {
722726
let mismatchType: string | undefined
723727
let mismatchKey: string | undefined
@@ -748,6 +752,12 @@ function propHasMismatch(
748752
}
749753
}
750754
}
755+
756+
const cssVars = instance?.getCssVars?.()
757+
for (const key in cssVars) {
758+
expectedMap.set(`--${key}`, String(cssVars[key]))
759+
}
760+
751761
if (!isMapEqual(actualMap, expectedMap)) {
752762
mismatchType = mismatchKey = 'style'
753763
}

‎packages/runtime-dom/src/helpers/useCssVars.ts

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>) {
3232
).forEach(node => setVarsOnNode(node, vars))
3333
})
3434

35+
if (__DEV__) {
36+
instance.getCssVars = () => getter(instance.proxy)
37+
}
38+
3539
const setVars = () => {
3640
const vars = getter(instance.proxy)
3741
setVarsOnVNode(instance.subTree, vars)

0 commit comments

Comments
 (0)
Please sign in to comment.