Просмотр исходного кода

fix(compiler-ssr): fix attr fallthrough for transition/keep-alive as template root

fix #3981
Evan You 4 лет назад
Родитель
Сommit
9f6f8b35c1

+ 4 - 3
packages/compiler-ssr/__tests__/ssrComponent.spec.ts

@@ -269,9 +269,10 @@ describe('ssr: components', () => {
     test('built-in fallthroughs', () => {
       expect(compile(`<transition><div/></transition>`).code)
         .toMatchInlineSnapshot(`
-        "
+        "const { ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
+
         return function ssrRender(_ctx, _push, _parent, _attrs) {
-          _push(\`<div></div>\`)
+          _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
         }"
       `)
 
@@ -283,7 +284,7 @@ describe('ssr: components', () => {
         return function ssrRender(_ctx, _push, _parent, _attrs) {
           const _component_foo = _resolveComponent(\\"foo\\")
 
-          _push(_ssrRenderComponent(_component_foo, null, null, _parent))
+          _push(_ssrRenderComponent(_component_foo, _attrs, null, _parent))
         }"
       `)
     })

+ 14 - 1
packages/compiler-ssr/src/transforms/ssrInjectFallthroughAttrs.ts

@@ -7,7 +7,8 @@ import {
   RootNode,
   TemplateChildNode,
   ParentNode,
-  findDir
+  findDir,
+  isBuiltInType
 } from '@vue/compiler-dom'
 
 const hasSingleChild = (node: ParentNode): boolean =>
@@ -21,6 +22,18 @@ export const ssrInjectFallthroughAttrs: NodeTransform = (node, context) => {
     context.identifiers._attrs = 1
   }
 
+  if (
+    node.type === NodeTypes.ELEMENT &&
+    node.tagType === ElementTypes.COMPONENT &&
+    (isBuiltInType(node.tag, 'Transition') ||
+      isBuiltInType(node.tag, 'KeepAlive'))
+  ) {
+    if (hasSingleChild(node)) {
+      injectFallthroughAttrs(node.children[0])
+    }
+    return
+  }
+
   const parent = context.parent
   if (!parent || parent.type !== NodeTypes.ROOT) {
     return

+ 2 - 1
packages/compiler-ssr/src/transforms/ssrTransformComponent.ts

@@ -180,7 +180,8 @@ export function ssrProcessComponent(
     } else if (component === TRANSITION_GROUP) {
       return ssrProcessTransitionGroup(node, context)
     } else {
-      // real fall-through (e.g. KeepAlive): just render its children.
+      // real fall-through: Transition / KeepAlive
+      // just render its children.
       processChildren(node.children, context)
     }
   } else {