fix(ssr): render fallthrough attributes for transition-group with tag
fix #5141
This commit is contained in:
@@ -48,7 +48,10 @@ import {
|
||||
ssrProcessSuspense,
|
||||
ssrTransformSuspense
|
||||
} from './ssrTransformSuspense'
|
||||
import { ssrProcessTransitionGroup } from './ssrTransformTransitionGroup'
|
||||
import {
|
||||
ssrProcessTransitionGroup,
|
||||
ssrTransformTransitionGroup
|
||||
} from './ssrTransformTransitionGroup'
|
||||
import { isSymbol, isObject, isArray } from '@vue/shared'
|
||||
import { buildSSRProps } from './ssrTransformElement'
|
||||
|
||||
@@ -95,7 +98,10 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
|
||||
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.
|
||||
|
||||
@@ -1,16 +1,71 @@
|
||||
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(
|
||||
@@ -30,7 +85,11 @@ export function ssrProcessTransitionGroup(
|
||||
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}>`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user