fix(ssr): render fallthrough attributes for transition-group with tag
fix #5141
This commit is contained in:
parent
1035c6b51b
commit
aed10c5072
@ -26,10 +26,10 @@ describe('transition-group', () => {
|
||||
`<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>\`)
|
||||
})
|
||||
@ -44,10 +44,14 @@ describe('transition-group', () => {
|
||||
`<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>\`)
|
||||
})
|
||||
@ -85,4 +89,23 @@ describe('transition-group', () => {
|
||||
}"
|
||||
`)
|
||||
})
|
||||
|
||||
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>\`)
|
||||
}"
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
@ -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}>`)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user