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

Lines changed: 35 additions & 0 deletions
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

Lines changed: 22 additions & 21 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy