fix(hydration): handle transition appear hydration edge case (#13339)
close #13335
This commit is contained in:
parent
d15dce3142
commit
35aeae7fa3
|
@ -1654,6 +1654,29 @@ describe('SSR hydration', () => {
|
||||||
expect(`mismatch`).not.toHaveBeenWarned()
|
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', () => {
|
test('transition appear with v-if', () => {
|
||||||
const show = false
|
const show = false
|
||||||
const { vnode, container } = mountWithHydration(
|
const { vnode, container } = mountWithHydration(
|
||||||
|
|
|
@ -398,9 +398,11 @@ export function createHydrationFunctions(
|
||||||
parentComponent.vnode.props.appear
|
parentComponent.vnode.props.appear
|
||||||
|
|
||||||
const content = (el as HTMLTemplateElement).content
|
const content = (el as HTMLTemplateElement).content
|
||||||
.firstChild as Element
|
.firstChild as Element & { $cls?: string }
|
||||||
|
|
||||||
if (needCallTransitionHooks) {
|
if (needCallTransitionHooks) {
|
||||||
|
const cls = content.getAttribute('class')
|
||||||
|
if (cls) content.$cls = cls
|
||||||
transition!.beforeEnter(content)
|
transition!.beforeEnter(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,7 +788,7 @@ export function createHydrationFunctions(
|
||||||
* Dev only
|
* Dev only
|
||||||
*/
|
*/
|
||||||
function propHasMismatch(
|
function propHasMismatch(
|
||||||
el: Element,
|
el: Element & { $cls?: string },
|
||||||
key: string,
|
key: string,
|
||||||
clientValue: any,
|
clientValue: any,
|
||||||
vnode: VNode,
|
vnode: VNode,
|
||||||
|
@ -799,7 +801,12 @@ function propHasMismatch(
|
||||||
if (key === 'class') {
|
if (key === 'class') {
|
||||||
// classes might be in different order, but that doesn't affect cascade
|
// 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.
|
// so we just need to check if the class lists contain the same classes.
|
||||||
actual = el.getAttribute('class')
|
if (el.$cls) {
|
||||||
|
actual = el.$cls
|
||||||
|
delete el.$cls
|
||||||
|
} else {
|
||||||
|
actual = el.getAttribute('class')
|
||||||
|
}
|
||||||
expected = normalizeClass(clientValue)
|
expected = normalizeClass(clientValue)
|
||||||
if (!isSetEqual(toClassSet(actual || ''), toClassSet(expected))) {
|
if (!isSetEqual(toClassSet(actual || ''), toClassSet(expected))) {
|
||||||
mismatchType = MismatchTypes.CLASS
|
mismatchType = MismatchTypes.CLASS
|
||||||
|
|
Loading…
Reference in New Issue