]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): fix the bug that multi slot scope id does not work on component (#6100)
authormmis1000 <2993977+mmis1000@users.noreply.github.com>
Thu, 30 May 2024 09:43:34 +0000 (17:43 +0800)
committerGitHub <noreply@github.com>
Thu, 30 May 2024 09:43:34 +0000 (17:43 +0800)
close #6093

packages/server-renderer/__tests__/ssrScopeId.spec.ts
packages/server-renderer/src/render.ts

index f9d356065d0c8539608b99cb290e25a34cffe2b5..4ceb865fb50faefdbb8cf9c674fa36ee887c9f43 100644 (file)
@@ -179,4 +179,94 @@ describe('ssr: scopedId runtime behavior', () => {
     const result = await renderToString(createApp(Comp)) // output: `<div></div>`
     expect(result).toBe(`<div parent></div>`)
   })
+
+  // #6093
+  test(':slotted on forwarded slots on component', async () => {
+    const Wrapper = {
+      __scopeId: 'wrapper',
+      ssrRender: (ctx: any, push: any, parent: any, attrs: any) => {
+        // <div class="wrapper"><slot/></div>
+        push(
+          `<div${ssrRenderAttrs(
+            mergeProps({ class: 'wrapper' }, attrs),
+          )} wrapper>`,
+        )
+        ssrRenderSlot(
+          ctx.$slots,
+          'default',
+          {},
+          null,
+          push,
+          parent,
+          'wrapper-s',
+        )
+        push(`</div>`)
+      },
+    }
+
+    const Slotted = {
+      __scopeId: 'slotted',
+      ssrRender: (ctx: any, push: any, parent: any, attrs: any) => {
+        // <Wrapper><slot/></Wrapper>
+        push(
+          ssrRenderComponent(
+            Wrapper,
+            attrs,
+            {
+              default: withCtx(
+                (_: any, push: any, parent: any, scopeId: string) => {
+                  ssrRenderSlot(
+                    ctx.$slots,
+                    'default',
+                    {},
+                    null,
+                    push,
+                    parent,
+                    'slotted-s' + scopeId,
+                  )
+                },
+              ),
+              _: 1,
+            } as any,
+            parent,
+          ),
+        )
+      },
+    }
+
+    const Child = {
+      ssrRender: (ctx: any, push: any, parent: any, attrs: any) => {
+        push(`<div${ssrRenderAttrs(attrs)}></div>`)
+      },
+    }
+
+    const Root = {
+      __scopeId: 'root',
+      // <Slotted><Child></Child></Slotted>
+      ssrRender: (_: any, push: any, parent: any, attrs: any) => {
+        push(
+          ssrRenderComponent(
+            Slotted,
+            attrs,
+            {
+              default: withCtx(
+                (_: any, push: any, parent: any, scopeId: string) => {
+                  push(ssrRenderComponent(Child, null, null, parent, scopeId))
+                },
+              ),
+              _: 1,
+            } as any,
+            parent,
+          ),
+        )
+      },
+    }
+
+    const result = await renderToString(createApp(Root))
+    expect(result).toBe(
+      `<div class="wrapper" root slotted wrapper>` +
+        `<!--[--><!--[--><div root slotted-s wrapper-s></div><!--]--><!--]-->` +
+        `</div>`,
+    )
+  })
 })
index 28a78c66843226403cf073fc681f4baee7ab2a4e..7e274c3b98115df7d82d2d6c817ba1393efc93e3 100644 (file)
@@ -181,7 +181,10 @@ function renderComponentSubTree(
 
       if (slotScopeId) {
         if (!hasCloned) attrs = { ...attrs }
-        attrs![slotScopeId.trim()] = ''
+        const slotScopeIdList = slotScopeId.trim().split(' ')
+        for (let i = 0; i < slotScopeIdList.length; i++) {
+          attrs![slotScopeIdList[i]] = ''
+        }
       }
 
       // set current rendering instance for asset resolution