]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(hydration): handling empty text node in slot
authordaiwei <daiwei521@126.com>
Tue, 5 Aug 2025 14:10:20 +0000 (22:10 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 5 Aug 2025 14:10:20 +0000 (22:10 +0800)
packages/runtime-vapor/__tests__/hydration.spec.ts
packages/runtime-vapor/src/dom/hydration.ts

index 26da9e3e746b6c70fee7ff3b6bec1a751e5afa65..6ec5f09e66d79bb12f1f4b0e7c30ff00ab06eb6e 100644 (file)
@@ -183,7 +183,7 @@ describe('Vapor Mode hydration', () => {
       )
     })
 
-    test('empty text nodes', async () => {
+    test('empty text node', async () => {
       const data = reactive({ txt: '' })
       const { container } = await testHydration(
         `<template><div>{{ data.txt }}</div></template>`,
@@ -196,6 +196,26 @@ describe('Vapor Mode hydration', () => {
       await nextTick()
       expect(container.innerHTML).toMatchInlineSnapshot(`"<div>foo</div>"`)
     })
+
+    test('empty text node in slot', async () => {
+      const data = reactive({ txt: '' })
+      const { container } = await testHydration(
+        `<template><components.Child>{{data.txt}}</components.Child></template>`,
+        {
+          Child: `<template><slot/></template>`,
+        },
+        data,
+      )
+      expect(container.innerHTML).toMatchInlineSnapshot(
+        `"<!--[--> <!--]--><!--slot-->"`,
+      )
+
+      data.txt = 'foo'
+      await nextTick()
+      expect(container.innerHTML).toMatchInlineSnapshot(
+        `"<!--[-->foo<!--]--><!--slot-->"`,
+      )
+    })
   })
 
   describe('element', () => {
index 1f4df1f45408628c8c86571120def4b17725e9fa..8abd4ee4b5c7474c008934d65af031c8846482e5 100644 (file)
@@ -9,6 +9,7 @@ import {
 import {
   __next,
   __nthChild,
+  createTextNode,
   disableHydrationNodeLookup,
   enableHydrationNodeLookup,
 } from './node'
@@ -97,7 +98,19 @@ export const isComment = (node: Node, data: string): node is Anchor =>
  */
 function adoptTemplateImpl(node: Node, template: string): Node | null {
   if (!(template[0] === '<' && template[1] === '!')) {
-    while (node.nodeType === 8) node = node.nextSibling!
+    while (node.nodeType === 8) {
+      node = node.nextSibling!
+
+      // empty text node in slot
+      if (
+        template === ' ' &&
+        isComment(node, ']') &&
+        isComment(node.previousSibling!, '[')
+      ) {
+        node = node.parentNode!.insertBefore(createTextNode(' '), node)
+        break
+      }
+    }
   }
 
   if (__DEV__) {