fix(ssr): fix hydration error for slot outlet inside transition

fix #3989
This commit is contained in:
Evan You
2022-05-12 15:06:32 +08:00
parent da49c863a2
commit 9309b044bd
6 changed files with 67 additions and 14 deletions

View File

@@ -4,9 +4,13 @@ import {
processSlotOutlet,
createCallExpression,
SlotOutletNode,
createFunctionExpression
createFunctionExpression,
NodeTypes,
ElementTypes,
resolveComponentType,
TRANSITION
} from '@vue/compiler-dom'
import { SSR_RENDER_SLOT } from '../runtimeHelpers'
import { SSR_RENDER_SLOT, SSR_RENDER_SLOT_INNER } from '../runtimeHelpers'
import {
SSRTransformContext,
processChildrenAsStatement
@@ -31,10 +35,24 @@ export const ssrTransformSlotOutlet: NodeTransform = (node, context) => {
args.push(`"${context.scopeId}-s"`)
}
node.ssrCodegenNode = createCallExpression(
context.helper(SSR_RENDER_SLOT),
args
)
let method = SSR_RENDER_SLOT
// #3989
// check if this is a single slot inside a transition wrapper - since
// transition will unwrap the slot fragment into a single vnode at runtime,
// we need to avoid rendering the slot as a fragment.
const parent = context.parent
if (
parent &&
parent.type === NodeTypes.ELEMENT &&
parent.tagType === ElementTypes.COMPONENT &&
resolveComponentType(parent, context, true) === TRANSITION &&
parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1
) {
method = SSR_RENDER_SLOT_INNER
}
node.ssrCodegenNode = createCallExpression(context.helper(method), args)
}
}