Skip to content

Commit 35aeae7

Browse files
authored
fix(hydration): handle transition appear hydration edge case (#13339)
close #13335
1 parent d15dce3 commit 35aeae7

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,6 +1654,29 @@ describe('SSR hydration', () => {
16541654
expect(`mismatch`).not.toHaveBeenWarned()
16551655
})
16561656

1657+
test('transition appear work with pre-existing class', () => {
1658+
const { vnode, container } = mountWithHydration(
1659+
`<template><div class="foo">foo</div></template>`,
1660+
() =>
1661+
h(
1662+
Transition,
1663+
{ appear: true },
1664+
{
1665+
default: () => h('div', { class: 'foo' }, 'foo'),
1666+
},
1667+
),
1668+
)
1669+
expect(container.firstChild).toMatchInlineSnapshot(`
1670+
<div
1671+
class="foo v-enter-from v-enter-active"
1672+
>
1673+
foo
1674+
</div>
1675+
`)
1676+
expect(vnode.el).toBe(container.firstChild)
1677+
expect(`mismatch`).not.toHaveBeenWarned()
1678+
})
1679+
16571680
test('transition appear with v-if', () => {
16581681
const show = false
16591682
const { vnode, container } = mountWithHydration(

packages/runtime-core/src/hydration.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,11 @@ export function createHydrationFunctions(
398398
parentComponent.vnode.props.appear
399399

400400
const content = (el as HTMLTemplateElement).content
401-
.firstChild as Element
401+
.firstChild as Element & { $cls?: string }
402402

403403
if (needCallTransitionHooks) {
404+
const cls = content.getAttribute('class')
405+
if (cls) content.$cls = cls
404406
transition!.beforeEnter(content)
405407
}
406408

@@ -786,7 +788,7 @@ export function createHydrationFunctions(
786788
* Dev only
787789
*/
788790
function propHasMismatch(
789-
el: Element,
791+
el: Element & { $cls?: string },
790792
key: string,
791793
clientValue: any,
792794
vnode: VNode,
@@ -799,7 +801,12 @@ function propHasMismatch(
799801
if (key === 'class') {
800802
// classes might be in different order, but that doesn't affect cascade
801803
// so we just need to check if the class lists contain the same classes.
802-
actual = el.getAttribute('class')
804+
if (el.$cls) {
805+
actual = el.$cls
806+
delete el.$cls
807+
} else {
808+
actual = el.getAttribute('class')
809+
}
803810
expected = normalizeClass(clientValue)
804811
if (!isSetEqual(toClassSet(actual || ''), toClassSet(expected))) {
805812
mismatchType = MismatchTypes.CLASS

0 commit comments

Comments
 (0)