mirror of https://github.com/vuejs/core.git
fix(hydration): fix css vars hydration mismatch false positive on attr-fallthrough (#11190)
close #11188
This commit is contained in:
parent
80ba50d74c
commit
7ad67ced26
|
@ -1674,5 +1674,26 @@ describe('SSR hydration', () => {
|
|||
app.mount(container)
|
||||
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
// #11188
|
||||
test('css vars support fallthrough', () => {
|
||||
const container = document.createElement('div')
|
||||
container.innerHTML = `<div style="padding: 4px;--foo:red;"></div>`
|
||||
const app = createSSRApp({
|
||||
setup() {
|
||||
useCssVars(() => ({
|
||||
foo: 'red',
|
||||
}))
|
||||
return () => h(Child)
|
||||
},
|
||||
})
|
||||
const Child = {
|
||||
setup() {
|
||||
return () => h('div', { style: 'padding: 4px' })
|
||||
},
|
||||
}
|
||||
app.mount(container)
|
||||
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -766,18 +766,8 @@ function propHasMismatch(
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const root = instance?.subTree
|
||||
if (
|
||||
vnode === root ||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
(root?.type === Fragment && (root.children as VNode[]).includes(vnode))
|
||||
) {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const cssVars = instance?.getCssVars?.()
|
||||
for (const key in cssVars) {
|
||||
expectedMap.set(`--${key}`, String(cssVars[key]))
|
||||
}
|
||||
if (instance) {
|
||||
resolveCssVars(instance, vnode, expectedMap)
|
||||
}
|
||||
|
||||
if (!isMapEqual(actualMap, expectedMap)) {
|
||||
|
@ -854,10 +844,8 @@ function toStyleMap(str: string): Map<string, string> {
|
|||
const styleMap: Map<string, string> = new Map()
|
||||
for (const item of str.split(';')) {
|
||||
let [key, value] = item.split(':')
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
key = key?.trim()
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
value = value?.trim()
|
||||
key = key.trim()
|
||||
value = value && value.trim()
|
||||
if (key && value) {
|
||||
styleMap.set(key, value)
|
||||
}
|
||||
|
@ -876,3 +864,26 @@ function isMapEqual(a: Map<string, string>, b: Map<string, string>): boolean {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function resolveCssVars(
|
||||
instance: ComponentInternalInstance,
|
||||
vnode: VNode,
|
||||
expectedMap: Map<string, string>,
|
||||
) {
|
||||
const root = instance.subTree
|
||||
if (
|
||||
instance.getCssVars &&
|
||||
(vnode === root ||
|
||||
(root &&
|
||||
root.type === Fragment &&
|
||||
(root.children as VNode[]).includes(vnode)))
|
||||
) {
|
||||
const cssVars = instance.getCssVars()
|
||||
for (const key in cssVars) {
|
||||
expectedMap.set(`--${key}`, String(cssVars[key]))
|
||||
}
|
||||
}
|
||||
if (vnode === root && instance.parent) {
|
||||
resolveCssVars(instance.parent, instance.vnode, expectedMap)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue