Skip to content

Commit e70f4c4

Browse files
authored
fix(hydration): handle appear transition before patch props (#9837)
close #9832
1 parent 0a387df commit e70f4c4

File tree

2 files changed

+57
-21
lines changed

2 files changed

+57
-21
lines changed

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

+35
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,41 @@ describe('SSR hydration', () => {
11141114
expect(`mismatch`).not.toHaveBeenWarned()
11151115
})
11161116

1117+
test('transition appear w/ event listener', async () => {
1118+
const container = document.createElement('div')
1119+
container.innerHTML = `<template><button>0</button></template>`
1120+
createSSRApp({
1121+
data() {
1122+
return {
1123+
count: 0
1124+
}
1125+
},
1126+
template: `
1127+
<Transition appear>
1128+
<button @click="count++">{{count}}</button>
1129+
</Transition>
1130+
`
1131+
}).mount(container)
1132+
1133+
expect(container.firstChild).toMatchInlineSnapshot(`
1134+
<button
1135+
class="v-enter-from v-enter-active"
1136+
>
1137+
0
1138+
</button>
1139+
`)
1140+
1141+
triggerEvent('click', container.querySelector('button')!)
1142+
await nextTick()
1143+
expect(container.firstChild).toMatchInlineSnapshot(`
1144+
<button
1145+
class="v-enter-from v-enter-active"
1146+
>
1147+
1
1148+
</button>
1149+
`)
1150+
})
1151+
11171152
describe('mismatch handling', () => {
11181153
test('text node', () => {
11191154
const { container } = mountWithHydration(`foo`, () => 'bar')

packages/runtime-core/src/hydration.ts

+22-21
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,28 @@ export function createHydrationFunctions(
344344
if (dirs) {
345345
invokeDirectiveHook(vnode, null, parentComponent, 'created')
346346
}
347+
348+
// handle appear transition
349+
let needCallTransitionHooks = false
350+
if (isTemplateNode(el)) {
351+
needCallTransitionHooks =
352+
needTransition(parentSuspense, transition) &&
353+
parentComponent &&
354+
parentComponent.vnode.props &&
355+
parentComponent.vnode.props.appear
356+
357+
const content = (el as HTMLTemplateElement).content
358+
.firstChild as Element
359+
360+
if (needCallTransitionHooks) {
361+
transition!.beforeEnter(content)
362+
}
363+
364+
// replace <template> node with inner children
365+
replaceNode(content, el, parentComponent)
366+
vnode.el = el = content
367+
}
368+
347369
// props
348370
if (props) {
349371
if (
@@ -390,27 +412,6 @@ export function createHydrationFunctions(
390412
invokeVNodeHook(vnodeHooks, parentComponent, vnode)
391413
}
392414

393-
// handle appear transition
394-
let needCallTransitionHooks = false
395-
if (isTemplateNode(el)) {
396-
needCallTransitionHooks =
397-
needTransition(parentSuspense, transition) &&
398-
parentComponent &&
399-
parentComponent.vnode.props &&
400-
parentComponent.vnode.props.appear
401-
402-
const content = (el as HTMLTemplateElement).content
403-
.firstChild as Element
404-
405-
if (needCallTransitionHooks) {
406-
transition!.beforeEnter(content)
407-
}
408-
409-
// replace <template> node with inner children
410-
replaceNode(content, el, parentComponent)
411-
vnode.el = el = content
412-
}
413-
414415
if (dirs) {
415416
invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')
416417
}

0 commit comments

Comments
 (0)