]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(hydration): the component vnode's el should be updated when a mismatch occurs...
authorlinzhe <40790268+linzhe141@users.noreply.github.com>
Fri, 15 Nov 2024 10:18:58 +0000 (18:18 +0800)
committerGitHub <noreply@github.com>
Fri, 15 Nov 2024 10:18:58 +0000 (18:18 +0800)
close #12253

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

index a1fb8cde33f32aba5dee62934d9a5bc2725c4939..45093550bcee1acb7c3f190eec558cc434d4b604 100644 (file)
@@ -21,6 +21,7 @@ import {
   h,
   nextTick,
   onMounted,
+  onServerPrefetch,
   openBlock,
   reactive,
   ref,
@@ -518,6 +519,45 @@ describe('SSR hydration', () => {
     )
   })
 
+  test('with data-allow-mismatch component when using onServerPrefetch', async () => {
+    const Comp = {
+      template: `
+        <div>Comp2</div>
+      `,
+    }
+    let foo: any
+    const App = {
+      setup() {
+        const flag = ref(true)
+        foo = () => {
+          flag.value = false
+        }
+        onServerPrefetch(() => (flag.value = false))
+        return { flag }
+      },
+      components: {
+        Comp,
+      },
+      template: `
+        <span data-allow-mismatch>
+          <Comp v-if="flag"></Comp>
+        </span>
+      `,
+    }
+    // hydrate
+    const container = document.createElement('div')
+    container.innerHTML = await renderToString(h(App))
+    createSSRApp(App).mount(container)
+    expect(container.innerHTML).toBe(
+      '<span data-allow-mismatch=""><div>Comp2</div></span>',
+    )
+    foo()
+    await nextTick()
+    expect(container.innerHTML).toBe(
+      '<span data-allow-mismatch=""><!--v-if--></span>',
+    )
+  })
+
   test('Teleport unmount (full integration)', async () => {
     const Comp1 = {
       template: `
index c49db529c38a486e470b64f9df88ea0a358d767c..41ae64cd19ea5aac569dcce51e3427b5e2f81ad8 100644 (file)
@@ -41,6 +41,7 @@ import {
 import type { TeleportImpl, TeleportVNode } from './components/Teleport'
 import { isAsyncWrapper } from './apiAsyncComponent'
 import { isReactive } from '@vue/reactivity'
+import { updateHOCHostEl } from './componentRenderUtils'
 
 export type RootHydrateFunction = (
   vnode: VNode<Node, Element>,
@@ -716,6 +717,11 @@ export function createHydrationFunctions(
       getContainerType(container),
       slotScopeIds,
     )
+    // the component vnode's el should be updated when a mismatch occurs.
+    if (parentComponent) {
+      parentComponent.vnode.el = vnode.el
+      updateHOCHostEl(parentComponent, vnode.el)
+    }
     return next
   }