diff --git a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts index 82122e621c7..4ca320b78b5 100644 --- a/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrTransitionGroup.spec.ts @@ -11,11 +11,18 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { + const _tag = (_attrs && typeof _attrs.tag === 'string') ? _attrs.tag : '' + if (_tag) { + _push(\`<\${_tag}>\`) + } _push(\`\`) _ssrRenderList(_ctx.list, (i) => { _push(\`
\`) }) _push(\`\`) + if (_tag) { + _push(\`\`) + } }" `) }) @@ -114,6 +121,10 @@ describe('transition-group', () => { "const { ssrRenderList: _ssrRenderList } = require("vue/server-renderer") return function ssrRender(_ctx, _push, _parent, _attrs) { + const _tag = (_attrs && typeof _attrs.tag === 'string') ? _attrs.tag : '' + if (_tag) { + _push(\`<\${_tag}>\`) + } _push(\`\`) _ssrRenderList(10, (i) => { _push(\`
\`) @@ -125,6 +136,9 @@ describe('transition-group', () => { _push(\`
ok
\`) } _push(\`\`) + if (_tag) { + _push(\`\`) + } }" `) }) diff --git a/packages/compiler-ssr/src/ssrCodegenTransform.ts b/packages/compiler-ssr/src/ssrCodegenTransform.ts index 536cbb5c1e9..0d09887317f 100644 --- a/packages/compiler-ssr/src/ssrCodegenTransform.ts +++ b/packages/compiler-ssr/src/ssrCodegenTransform.ts @@ -4,6 +4,7 @@ import { type CompilerError, type CompilerOptions, ElementTypes, + type ExpressionNode, type IfStatement, type JSChildNode, NodeTypes, @@ -84,7 +85,7 @@ export interface SSRTransformContext { onError: (error: CompilerError) => void helper(name: T): T pushStringPart(part: TemplateLiteral['elements'][0]): void - pushStatement(statement: IfStatement | CallExpression): void + pushStatement(statement: IfStatement | CallExpression | ExpressionNode): void } function createSSRTransformContext( diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index 27ddebec103..831dffb8393 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -6,7 +6,10 @@ import { NodeTypes, type TransformContext, buildProps, + createBlockStatement, createCallExpression, + createIfStatement, + createSimpleExpression, findProp, } from '@vue/compiler-dom' import { SSR_RENDER_ATTRS } from '../runtimeHelpers' @@ -112,7 +115,38 @@ export function ssrProcessTransitionGroup( context.pushStringPart(``) } } else { + // _attrs may contain tag property + const hasFallthroughAttrs = node.props.some( + p => + p.type === NodeTypes.DIRECTIVE && + p.name === 'bind' && + p.exp && + p.exp.type === NodeTypes.SIMPLE_EXPRESSION && + p.exp.content === '_attrs', + ) + if (hasFallthroughAttrs) { + context.pushStatement( + createSimpleExpression( + `const _tag = (_attrs && typeof _attrs.tag === 'string') ? _attrs.tag : ''`, + ), + ) + context.pushStatement( + createIfStatement( + createSimpleExpression('_tag'), + createBlockStatement([createSimpleExpression('_push(`<${_tag}>`)')]), + ), + ) + } // fragment processChildren(node, context, true, true, true) + + if (hasFallthroughAttrs) { + context.pushStatement( + createIfStatement( + createSimpleExpression('_tag'), + createBlockStatement([createSimpleExpression('_push(``)')]), + ), + ) + } } } diff --git a/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts b/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts index e8cfa75e77c..66f6688b7f3 100644 --- a/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts +++ b/packages/server-renderer/__tests__/ssrAttrFallthrough.spec.ts @@ -75,4 +75,20 @@ describe('ssr: attr fallthrough', () => { `
`, ) }) + + // #12827 + test('with transition-group tag name', async () => { + expect( + await renderToString( + createApp({ + components: { + one: { + template: ``, + }, + }, + template: `

{{i}}

`, + }), + ), + ).toBe(`

1

2

`) + }) })