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>`
|
`<transition-group tag="ul"><div v-for="i in list"/></transition-group>`
|
||||||
).code
|
).code
|
||||||
).toMatchInlineSnapshot(`
|
).toMatchInlineSnapshot(`
|
||||||
"const { ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
|
"const { ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
|
||||||
|
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
_push(\`<ul>\`)
|
_push(\`<ul\${_ssrRenderAttrs(_attrs)}>\`)
|
||||||
_ssrRenderList(_ctx.list, (i) => {
|
_ssrRenderList(_ctx.list, (i) => {
|
||||||
_push(\`<div></div>\`)
|
_push(\`<div></div>\`)
|
||||||
})
|
})
|
||||||
@ -44,10 +44,14 @@ describe('transition-group', () => {
|
|||||||
`<transition-group :tag="someTag"><div v-for="i in list"/></transition-group>`
|
`<transition-group :tag="someTag"><div v-for="i in list"/></transition-group>`
|
||||||
).code
|
).code
|
||||||
).toMatchInlineSnapshot(`
|
).toMatchInlineSnapshot(`
|
||||||
"const { ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
|
"const { ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require(\\"vue/server-renderer\\")
|
||||||
|
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
_push(\`<\${_ctx.someTag}>\`)
|
_push(\`<\${
|
||||||
|
_ctx.someTag
|
||||||
|
}\${
|
||||||
|
_ssrRenderAttrs(_attrs)
|
||||||
|
}>\`)
|
||||||
_ssrRenderList(_ctx.list, (i) => {
|
_ssrRenderList(_ctx.list, (i) => {
|
||||||
_push(\`<div></div>\`)
|
_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,
|
ssrProcessSuspense,
|
||||||
ssrTransformSuspense
|
ssrTransformSuspense
|
||||||
} from './ssrTransformSuspense'
|
} from './ssrTransformSuspense'
|
||||||
import { ssrProcessTransitionGroup } from './ssrTransformTransitionGroup'
|
import {
|
||||||
|
ssrProcessTransitionGroup,
|
||||||
|
ssrTransformTransitionGroup
|
||||||
|
} from './ssrTransformTransitionGroup'
|
||||||
import { isSymbol, isObject, isArray } from '@vue/shared'
|
import { isSymbol, isObject, isArray } from '@vue/shared'
|
||||||
import { buildSSRProps } from './ssrTransformElement'
|
import { buildSSRProps } from './ssrTransformElement'
|
||||||
|
|
||||||
@ -95,7 +98,10 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
|
|||||||
if (component === SUSPENSE) {
|
if (component === SUSPENSE) {
|
||||||
return ssrTransformSuspense(node, context)
|
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.
|
// 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 { 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(
|
export function ssrProcessTransitionGroup(
|
||||||
node: ComponentNode,
|
node: ComponentNode,
|
||||||
context: SSRTransformContext
|
context: SSRTransformContext
|
||||||
) {
|
) {
|
||||||
const tag = findProp(node, 'tag')
|
const entry = wipMap.get(node)
|
||||||
if (tag) {
|
if (entry) {
|
||||||
|
const { tag, propsExp } = entry
|
||||||
if (tag.type === NodeTypes.DIRECTIVE) {
|
if (tag.type === NodeTypes.DIRECTIVE) {
|
||||||
// dynamic :tag
|
// dynamic :tag
|
||||||
context.pushStringPart(`<`)
|
context.pushStringPart(`<`)
|
||||||
context.pushStringPart(tag.exp!)
|
context.pushStringPart(tag.exp!)
|
||||||
|
if (propsExp) {
|
||||||
|
context.pushStringPart(propsExp)
|
||||||
|
}
|
||||||
context.pushStringPart(`>`)
|
context.pushStringPart(`>`)
|
||||||
|
|
||||||
processChildren(
|
processChildren(
|
||||||
@ -30,7 +85,11 @@ export function ssrProcessTransitionGroup(
|
|||||||
context.pushStringPart(`>`)
|
context.pushStringPart(`>`)
|
||||||
} else {
|
} else {
|
||||||
// static tag
|
// static tag
|
||||||
context.pushStringPart(`<${tag.value!.content}>`)
|
context.pushStringPart(`<${tag.value!.content}`)
|
||||||
|
if (propsExp) {
|
||||||
|
context.pushStringPart(propsExp)
|
||||||
|
}
|
||||||
|
context.pushStringPart(`>`)
|
||||||
processChildren(node, context, false, true)
|
processChildren(node, context, false, true)
|
||||||
context.pushStringPart(`</${tag.value!.content}>`)
|
context.pushStringPart(`</${tag.value!.content}>`)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user