fix(hydration): handle transition appear hydration edge case (#13339)

close #13335
This commit is contained in:
edison 2025-05-20 08:28:43 +08:00 committed by GitHub
parent d15dce3142
commit 35aeae7fa3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 3 deletions

View File

@ -1654,6 +1654,29 @@ describe('SSR hydration', () => {
expect(`mismatch`).not.toHaveBeenWarned()
})
test('transition appear work with pre-existing class', () => {
const { vnode, container } = mountWithHydration(
`<template><div class="foo">foo</div></template>`,
() =>
h(
Transition,
{ appear: true },
{
default: () => h('div', { class: 'foo' }, 'foo'),
},
),
)
expect(container.firstChild).toMatchInlineSnapshot(`
<div
class="foo v-enter-from v-enter-active"
>
foo
</div>
`)
expect(vnode.el).toBe(container.firstChild)
expect(`mismatch`).not.toHaveBeenWarned()
})
test('transition appear with v-if', () => {
const show = false
const { vnode, container } = mountWithHydration(

View File

@ -398,9 +398,11 @@ export function createHydrationFunctions(
parentComponent.vnode.props.appear
const content = (el as HTMLTemplateElement).content
.firstChild as Element
.firstChild as Element & { $cls?: string }
if (needCallTransitionHooks) {
const cls = content.getAttribute('class')
if (cls) content.$cls = cls
transition!.beforeEnter(content)
}
@ -786,7 +788,7 @@ export function createHydrationFunctions(
* Dev only
*/
function propHasMismatch(
el: Element,
el: Element & { $cls?: string },
key: string,
clientValue: any,
vnode: VNode,
@ -799,7 +801,12 @@ function propHasMismatch(
if (key === 'class') {
// classes might be in different order, but that doesn't affect cascade
// so we just need to check if the class lists contain the same classes.
if (el.$cls) {
actual = el.$cls
delete el.$cls
} else {
actual = el.getAttribute('class')
}
expected = normalizeClass(clientValue)
if (!isSetEqual(toClassSet(actual || ''), toClassSet(expected))) {
mismatchType = MismatchTypes.CLASS