mirror of https://github.com/vuejs/core.git
fix(ssr): fix hydration error for slot outlet inside transition-group (#9937)
close #9933
This commit is contained in:
parent
c3fd577177
commit
6cb00ed0f9
|
@ -127,4 +127,20 @@ describe('ssr: <slot>', () => {
|
||||||
}"
|
}"
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('inside transition-group', () => {
|
||||||
|
const { code } = compile(
|
||||||
|
`<TransitionGroup tag="div"><slot/></TransitionGroup>`,
|
||||||
|
)
|
||||||
|
expect(code).toMatch(ssrHelpers[SSR_RENDER_SLOT_INNER])
|
||||||
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
"const { ssrRenderSlotInner: _ssrRenderSlotInner, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
|
||||||
|
|
||||||
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}>\`)
|
||||||
|
_ssrRenderSlotInner(_ctx.$slots, "default", {}, null, _push, _parent, null, true)
|
||||||
|
_push(\`</div>\`)
|
||||||
|
}"
|
||||||
|
`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
type SlotOutletNode,
|
type SlotOutletNode,
|
||||||
TRANSITION,
|
TRANSITION,
|
||||||
|
TRANSITION_GROUP,
|
||||||
createCallExpression,
|
createCallExpression,
|
||||||
createFunctionExpression,
|
createFunctionExpression,
|
||||||
isSlotOutlet,
|
isSlotOutlet,
|
||||||
|
@ -37,16 +38,19 @@ export const ssrTransformSlotOutlet: NodeTransform = (node, context) => {
|
||||||
|
|
||||||
let method = SSR_RENDER_SLOT
|
let method = SSR_RENDER_SLOT
|
||||||
|
|
||||||
// #3989
|
// #3989, #9933
|
||||||
// check if this is a single slot inside a transition wrapper - since
|
// check if this is a single slot inside a transition wrapper - since
|
||||||
// transition will unwrap the slot fragment into a single vnode at runtime,
|
// transition/transition-group will unwrap the slot fragment into vnode(s) at runtime,
|
||||||
// we need to avoid rendering the slot as a fragment.
|
// we need to avoid rendering the slot as a fragment.
|
||||||
const parent = context.parent
|
const parent = context.parent
|
||||||
|
let componentType
|
||||||
if (
|
if (
|
||||||
parent &&
|
parent &&
|
||||||
parent.type === NodeTypes.ELEMENT &&
|
parent.type === NodeTypes.ELEMENT &&
|
||||||
parent.tagType === ElementTypes.COMPONENT &&
|
parent.tagType === ElementTypes.COMPONENT &&
|
||||||
resolveComponentType(parent, context, true) === TRANSITION &&
|
((componentType = resolveComponentType(parent, context, true)) ===
|
||||||
|
TRANSITION ||
|
||||||
|
componentType === TRANSITION_GROUP) &&
|
||||||
parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1
|
parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1
|
||||||
) {
|
) {
|
||||||
method = SSR_RENDER_SLOT_INNER
|
method = SSR_RENDER_SLOT_INNER
|
||||||
|
|
Loading…
Reference in New Issue