Skip to content

Commit

Permalink
fix(hydration): fix css vars hydration mismatch false positive on att…
Browse files Browse the repository at this point in the history
…r-fallthrough
  • Loading branch information
yangchangtao committed Jun 21, 2024
1 parent 1c3327a commit ce201c1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
21 changes: 21 additions & 0 deletions packages/runtime-core/__tests__/hydration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
})
})
31 changes: 22 additions & 9 deletions packages/runtime-core/src/hydration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -766,18 +766,31 @@ function propHasMismatch(
}
}

// eslint-disable-next-line no-restricted-syntax
const root = instance?.subTree
const root = instance ? instance.subTree : null
let cssVars: Record<string, string> | null | undefined
if (
vnode === root ||
// eslint-disable-next-line no-restricted-syntax
(root?.type === Fragment && (root.children as VNode[]).includes(vnode))
(root &&
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]))
}
cssVars = instance && instance.getCssVars && instance.getCssVars()
}

const parentInstance = instance ? instance.parent : null
if (
instance &&
parentInstance &&
((parentInstance.subTree.children &&
(parentInstance.subTree.children as VNode[]).includes(
instance.vnode,
)) ||
parentInstance.subTree.component === instance)
) {
cssVars = parentInstance.getCssVars && parentInstance.getCssVars()
}
for (const key in cssVars) {
expectedMap.set(`--${key}`, String(cssVars[key]))
}

if (!isMapEqual(actualMap, expectedMap)) {
Expand Down

0 comments on commit ce201c1

Please sign in to comment.