]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(hydration): handle v-if node mismatch
authordaiwei <daiwei521@126.com>
Sat, 1 Feb 2025 03:28:21 +0000 (11:28 +0800)
committerdaiwei <daiwei521@126.com>
Sat, 1 Feb 2025 03:28:21 +0000 (11:28 +0800)
packages/runtime-core/__tests__/hydration.spec.ts
packages/runtime-core/src/hydration.ts

index 56011d063599f0a92a29b56cc18813deaa89e51c..8daf68c27c8709fabe38780d94581ec1690d467e 100644 (file)
@@ -2299,6 +2299,16 @@ describe('SSR hydration', () => {
       expect(`Hydration node mismatch`).not.toHaveBeenWarned()
     })
 
+    test('comment mismatch (v-if)', () => {
+      const { container } = mountWithHydration(`<!--v-if-->`, () =>
+        h('div', { 'data-allow-mismatch': '' }, [h('span', 'value')]),
+      )
+      expect(container.innerHTML).toBe(
+        '<div data-allow-mismatch=""><span>value</span></div>',
+      )
+      expect(`Hydration node mismatch`).not.toHaveBeenWarned()
+    })
+
     test('comment mismatch (text)', () => {
       const { container } = mountWithHydration(
         `<div data-allow-mismatch="children">foobar</div>`,
index a94ff3568107e6c20d383eeb4e5e839012825ee2..aa94eb09619224f19b052ae1411215cda25d0392 100644 (file)
@@ -675,7 +675,10 @@ export function createHydrationFunctions(
     slotScopeIds: string[] | null,
     isFragment: boolean,
   ): Node | null => {
-    if (!isMismatchAllowed(node.parentElement!, MismatchTypes.CHILDREN)) {
+    if (
+      !isMismatchAllowed(node.parentElement!, MismatchTypes.CHILDREN) &&
+      !isCommentNodeMismatch(node, vnode)
+    ) {
       ;(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
         warn(
           `Hydration node mismatch:\n- rendered on server:`,
@@ -993,3 +996,12 @@ function isMismatchAllowed(
     return allowedAttr.split(',').includes(MismatchTypeString[allowedType])
   }
 }
+
+// data-allow-mismatch + v-if
+function isCommentNodeMismatch(node: Node, vnode: VNode): boolean {
+  if (node.nodeType !== DOMNodeTypes.COMMENT || !vnode.props) {
+    return false
+  }
+
+  return allowMismatchAttr in vnode.props
+}