]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(hydration): handle appear transition before patch props (#9837)
authoredison <daiwei521@126.com>
Sat, 16 Dec 2023 03:55:40 +0000 (11:55 +0800)
committerGitHub <noreply@github.com>
Sat, 16 Dec 2023 03:55:40 +0000 (11:55 +0800)
close #9832

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

index 2b85cc974a470d47269b1fccdf4b5b55e21fe0d3..39cb921bf607e3c387e59f07e8108c90787cb6c3 100644 (file)
@@ -1114,6 +1114,41 @@ describe('SSR hydration', () => {
     expect(`mismatch`).not.toHaveBeenWarned()
   })
 
+  test('transition appear w/ event listener', async () => {
+    const container = document.createElement('div')
+    container.innerHTML = `<template><button>0</button></template>`
+    createSSRApp({
+      data() {
+        return {
+          count: 0
+        }
+      },
+      template: `
+        <Transition appear>
+          <button @click="count++">{{count}}</button>
+        </Transition>
+      `
+    }).mount(container)
+
+    expect(container.firstChild).toMatchInlineSnapshot(`
+      <button
+        class="v-enter-from v-enter-active"
+      >
+        0
+      </button>
+    `)
+
+    triggerEvent('click', container.querySelector('button')!)
+    await nextTick()
+    expect(container.firstChild).toMatchInlineSnapshot(`
+      <button
+        class="v-enter-from v-enter-active"
+      >
+        1
+      </button>
+    `)
+  })
+
   describe('mismatch handling', () => {
     test('text node', () => {
       const { container } = mountWithHydration(`foo`, () => 'bar')
index 94d6e8f627700f25596b08b0c781e284fa40c070..1107bd6566db64edf49464c0ec3273eb1f8a3c5e 100644 (file)
@@ -344,6 +344,28 @@ export function createHydrationFunctions(
       if (dirs) {
         invokeDirectiveHook(vnode, null, parentComponent, 'created')
       }
+
+      // handle appear transition
+      let needCallTransitionHooks = false
+      if (isTemplateNode(el)) {
+        needCallTransitionHooks =
+          needTransition(parentSuspense, transition) &&
+          parentComponent &&
+          parentComponent.vnode.props &&
+          parentComponent.vnode.props.appear
+
+        const content = (el as HTMLTemplateElement).content
+          .firstChild as Element
+
+        if (needCallTransitionHooks) {
+          transition!.beforeEnter(content)
+        }
+
+        // replace <template> node with inner children
+        replaceNode(content, el, parentComponent)
+        vnode.el = el = content
+      }
+
       // props
       if (props) {
         if (
@@ -390,27 +412,6 @@ export function createHydrationFunctions(
         invokeVNodeHook(vnodeHooks, parentComponent, vnode)
       }
 
-      // handle appear transition
-      let needCallTransitionHooks = false
-      if (isTemplateNode(el)) {
-        needCallTransitionHooks =
-          needTransition(parentSuspense, transition) &&
-          parentComponent &&
-          parentComponent.vnode.props &&
-          parentComponent.vnode.props.appear
-
-        const content = (el as HTMLTemplateElement).content
-          .firstChild as Element
-
-        if (needCallTransitionHooks) {
-          transition!.beforeEnter(content)
-        }
-
-        // replace <template> node with inner children
-        replaceNode(content, el, parentComponent)
-        vnode.el = el = content
-      }
-
       if (dirs) {
         invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')
       }