`<transition-group tag="ul"><div v-for="i in list"/></transition-group>`
).code
).toMatchInlineSnapshot(`
- "const { ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
+ "const { ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent, _attrs) {
- _push(\`<ul>\`)
+ _push(\`<ul\${_ssrRenderAttrs(_attrs)}>\`)
_ssrRenderList(_ctx.list, (i) => {
_push(\`<div></div>\`)
})
`<transition-group :tag="someTag"><div v-for="i in list"/></transition-group>`
).code
).toMatchInlineSnapshot(`
- "const { ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
+ "const { ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent, _attrs) {
- _push(\`<\${_ctx.someTag}>\`)
+ _push(\`<\${
+ _ctx.someTag
+ }\${
+ _ssrRenderAttrs(_attrs)
+ }>\`)
_ssrRenderList(_ctx.list, (i) => {
_push(\`<div></div>\`)
})
}"
`)
})
+
+ test('attribute fallthrough', () => {
+ expect(
+ compile(
+ `<transition-group tag="ul" class="red" id="ok">
+ </transition-group>`
+ ).code
+ ).toMatchInlineSnapshot(`
+ "const { mergeProps: _mergeProps } = require(\\"vue\\")
+ const { ssrRenderAttrs: _ssrRenderAttrs } = require(\\"vue/server-renderer\\")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _push(\`<ul\${_ssrRenderAttrs(_mergeProps({
+ class: \\"red\\",
+ id: \\"ok\\"
+ }, _attrs))}></ul>\`)
+ }"
+ `)
+ })
})
ssrProcessSuspense,
ssrTransformSuspense
} from './ssrTransformSuspense'
-import { ssrProcessTransitionGroup } from './ssrTransformTransitionGroup'
+import {
+ ssrProcessTransitionGroup,
+ ssrTransformTransitionGroup
+} from './ssrTransformTransitionGroup'
import { isSymbol, isObject, isArray } from '@vue/shared'
import { buildSSRProps } from './ssrTransformElement'
if (component === SUSPENSE) {
return ssrTransformSuspense(node, context)
}
- return // built-in component: fallthrough
+ if (component === TRANSITION_GROUP) {
+ return ssrTransformTransitionGroup(node, context)
+ }
+ return // other built-in components: fallthrough
}
// Build the fallback vnode-based branch for the component's slots.
-import { ComponentNode, findProp, NodeTypes } from '@vue/compiler-dom'
+import {
+ AttributeNode,
+ buildProps,
+ ComponentNode,
+ createCallExpression,
+ DirectiveNode,
+ findProp,
+ JSChildNode,
+ NodeTypes,
+ TransformContext
+} from '@vue/compiler-dom'
+import { SSR_RENDER_ATTRS } from '../runtimeHelpers'
import { processChildren, SSRTransformContext } from '../ssrCodegenTransform'
+import { buildSSRProps } from './ssrTransformElement'
+const wipMap = new WeakMap<ComponentNode, WIPEntry>()
+
+interface WIPEntry {
+ tag: AttributeNode | DirectiveNode
+ propsExp: string | JSChildNode | null
+}
+
+// phase 1: build props
+export function ssrTransformTransitionGroup(
+ node: ComponentNode,
+ context: TransformContext
+) {
+ return () => {
+ const tag = findProp(node, 'tag')
+ if (tag) {
+ const otherProps = node.props.filter(p => p !== tag)
+ const { props, directives } = buildProps(
+ node,
+ context,
+ otherProps,
+ true, /* isComponent */
+ false, /* isDynamicComponent */
+ true /* ssr (skip event listeners) */
+ )
+ let propsExp = null
+ if (props || directives.length) {
+ propsExp = createCallExpression(context.helper(SSR_RENDER_ATTRS), [
+ buildSSRProps(props, directives, context)
+ ])
+ }
+ wipMap.set(node, {
+ tag,
+ propsExp
+ })
+ }
+ }
+}
+
+// phase 2: process children
export function ssrProcessTransitionGroup(
node: ComponentNode,
context: SSRTransformContext
) {
- const tag = findProp(node, 'tag')
- if (tag) {
+ const entry = wipMap.get(node)
+ if (entry) {
+ const { tag, propsExp } = entry
if (tag.type === NodeTypes.DIRECTIVE) {
// dynamic :tag
context.pushStringPart(`<`)
context.pushStringPart(tag.exp!)
+ if (propsExp) {
+ context.pushStringPart(propsExp)
+ }
context.pushStringPart(`>`)
processChildren(
context.pushStringPart(`>`)
} else {
// static tag
- context.pushStringPart(`<${tag.value!.content}>`)
+ context.pushStringPart(`<${tag.value!.content}`)
+ if (propsExp) {
+ context.pushStringPart(propsExp)
+ }
+ context.pushStringPart(`>`)
processChildren(node, context, false, true)
context.pushStringPart(`</${tag.value!.content}>`)
}