feat(ssr/suspense): suspense hydration
In order to support hydration of async components, server-rendered fragments must be explicitly marked with comment nodes.
This commit is contained in:
@@ -30,7 +30,8 @@ import {
|
||||
traverseNode,
|
||||
ExpressionNode,
|
||||
TemplateNode,
|
||||
SUSPENSE
|
||||
SUSPENSE,
|
||||
TRANSITION_GROUP
|
||||
} from '@vue/compiler-dom'
|
||||
import { SSR_RENDER_COMPONENT } from '../runtimeHelpers'
|
||||
import {
|
||||
@@ -151,7 +152,7 @@ export function ssrProcessComponent(
|
||||
return ssrProcessSuspense(node, context)
|
||||
} else {
|
||||
// real fall-through (e.g. KeepAlive): just render its children.
|
||||
processChildren(node.children, context)
|
||||
processChildren(node.children, context, component === TRANSITION_GROUP)
|
||||
}
|
||||
} else {
|
||||
// finish up slot function expressions from the 1st pass.
|
||||
@@ -167,6 +168,7 @@ export function ssrProcessComponent(
|
||||
processChildrenAsStatement(
|
||||
children,
|
||||
context,
|
||||
false,
|
||||
true /* withSlotScopeId */
|
||||
),
|
||||
vnodeBranch
|
||||
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
processFor,
|
||||
createCallExpression,
|
||||
createFunctionExpression,
|
||||
createForLoopParams
|
||||
createForLoopParams,
|
||||
NodeTypes
|
||||
} from '@vue/compiler-dom'
|
||||
import {
|
||||
SSRTransformContext,
|
||||
@@ -21,14 +22,23 @@ export const ssrTransformFor = createStructuralDirectiveTransform(
|
||||
// This is called during the 2nd transform pass to construct the SSR-sepcific
|
||||
// codegen nodes.
|
||||
export function ssrProcessFor(node: ForNode, context: SSRTransformContext) {
|
||||
const needFragmentWrapper =
|
||||
node.children.length !== 1 || node.children[0].type !== NodeTypes.ELEMENT
|
||||
const renderLoop = createFunctionExpression(
|
||||
createForLoopParams(node.parseResult)
|
||||
)
|
||||
renderLoop.body = processChildrenAsStatement(node.children, context)
|
||||
renderLoop.body = processChildrenAsStatement(
|
||||
node.children,
|
||||
context,
|
||||
needFragmentWrapper
|
||||
)
|
||||
// v-for always renders a fragment
|
||||
context.pushStringPart(`<!--1-->`)
|
||||
context.pushStatement(
|
||||
createCallExpression(context.helper(SSR_RENDER_LIST), [
|
||||
node.source,
|
||||
renderLoop
|
||||
])
|
||||
)
|
||||
context.pushStringPart(`<!--0-->`)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ import {
|
||||
IfNode,
|
||||
createIfStatement,
|
||||
createBlockStatement,
|
||||
createCallExpression
|
||||
createCallExpression,
|
||||
IfBranchNode,
|
||||
BlockStatement,
|
||||
NodeTypes
|
||||
} from '@vue/compiler-dom'
|
||||
import {
|
||||
SSRTransformContext,
|
||||
@@ -23,17 +26,14 @@ export function ssrProcessIf(node: IfNode, context: SSRTransformContext) {
|
||||
const [rootBranch] = node.branches
|
||||
const ifStatement = createIfStatement(
|
||||
rootBranch.condition!,
|
||||
processChildrenAsStatement(rootBranch.children, context)
|
||||
processIfBranch(rootBranch, context)
|
||||
)
|
||||
context.pushStatement(ifStatement)
|
||||
|
||||
let currentIf = ifStatement
|
||||
for (let i = 1; i < node.branches.length; i++) {
|
||||
const branch = node.branches[i]
|
||||
const branchBlockStatement = processChildrenAsStatement(
|
||||
branch.children,
|
||||
context
|
||||
)
|
||||
const branchBlockStatement = processIfBranch(branch, context)
|
||||
if (branch.condition) {
|
||||
// else-if
|
||||
currentIf = currentIf.alternate = createIfStatement(
|
||||
@@ -52,3 +52,15 @@ export function ssrProcessIf(node: IfNode, context: SSRTransformContext) {
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
function processIfBranch(
|
||||
branch: IfBranchNode,
|
||||
context: SSRTransformContext
|
||||
): BlockStatement {
|
||||
const { children } = branch
|
||||
const needFragmentWrapper =
|
||||
(children.length !== 1 || children[0].type !== NodeTypes.ELEMENT) &&
|
||||
// optimize away nested fragments when the only child is a ForNode
|
||||
!(children.length === 1 && children[0].type === NodeTypes.FOR)
|
||||
return processChildrenAsStatement(children, context, needFragmentWrapper)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user