]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): fix hydration error for slot outlet inside transition-group (#9937)
authoredison <daiwei521@126.com>
Sat, 30 Dec 2023 11:01:07 +0000 (19:01 +0800)
committerGitHub <noreply@github.com>
Sat, 30 Dec 2023 11:01:07 +0000 (19:01 +0800)
close #9933

packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts
packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts

index 977cc8027d033919fae6a30da43c1934f85062f2..655d68efbbc54fc5ee88000c6ec6bfd17e5135ff 100644 (file)
@@ -127,4 +127,20 @@ describe('ssr: <slot>', () => {
       }"
     `)
   })
+
+  test('inside transition-group', () => {
+    const { code } = compile(
+      `<TransitionGroup tag="div"><slot/></TransitionGroup>`,
+    )
+    expect(code).toMatch(ssrHelpers[SSR_RENDER_SLOT_INNER])
+    expect(code).toMatchInlineSnapshot(`
+      "const { ssrRenderSlotInner: _ssrRenderSlotInner, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
+
+      return function ssrRender(_ctx, _push, _parent, _attrs) {
+        _push(\`<div\${_ssrRenderAttrs(_attrs)}>\`)
+        _ssrRenderSlotInner(_ctx.$slots, "default", {}, null, _push, _parent, null, true)
+        _push(\`</div>\`)
+      }"
+    `)
+  })
 })
index b75b4d033661677b5e97fcac3fcf0984c03df4b5..ad08a23a4452dbb6ef291f439598c19f40b11fb0 100644 (file)
@@ -4,6 +4,7 @@ import {
   NodeTypes,
   type SlotOutletNode,
   TRANSITION,
+  TRANSITION_GROUP,
   createCallExpression,
   createFunctionExpression,
   isSlotOutlet,
@@ -37,16 +38,19 @@ export const ssrTransformSlotOutlet: NodeTransform = (node, context) => {
 
     let method = SSR_RENDER_SLOT
 
-    // #3989
+    // #3989, #9933
     // check if this is a single slot inside a transition wrapper - since
-    // transition will unwrap the slot fragment into a single vnode at runtime,
+    // transition/transition-group will unwrap the slot fragment into vnode(s) at runtime,
     // we need to avoid rendering the slot as a fragment.
     const parent = context.parent
+    let componentType
     if (
       parent &&
       parent.type === NodeTypes.ELEMENT &&
       parent.tagType === ElementTypes.COMPONENT &&
-      resolveComponentType(parent, context, true) === TRANSITION &&
+      ((componentType = resolveComponentType(parent, context, true)) ===
+        TRANSITION ||
+        componentType === TRANSITION_GROUP) &&
       parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1
     ) {
       method = SSR_RENDER_SLOT_INNER