wip(srr): slot outlet

This commit is contained in:
Evan You
2020-02-05 21:04:40 -05:00
parent 7a63103a11
commit 9b3b6962df
14 changed files with 263 additions and 120 deletions

View File

@@ -15,8 +15,9 @@ import {
} from '@vue/compiler-dom'
import { isString, escapeHtml, NO } from '@vue/shared'
import { SSR_INTERPOLATE, ssrHelpers } from './runtimeHelpers'
import { processIf } from './transforms/ssrVIf'
import { processFor } from './transforms/ssrVFor'
import { ssrProcessIf } from './transforms/ssrVIf'
import { ssrProcessFor } from './transforms/ssrVFor'
import { ssrProcessSlotOutlet } from './transforms/ssrTransformSlotOutlet'
// Because SSR codegen output is completely different from client-side output
// (e.g. multiple elements can be concatenated into a single template literal
@@ -119,7 +120,7 @@ export function processChildren(
} else if (child.tagType === ElementTypes.COMPONENT) {
// TODO
} else if (child.tagType === ElementTypes.SLOT) {
// TODO
ssrProcessSlotOutlet(child, context)
}
} else if (child.type === NodeTypes.TEXT) {
context.pushStringPart(escapeHtml(child.content))
@@ -128,9 +129,9 @@ export function processChildren(
createCallExpression(context.helper(SSR_INTERPOLATE), [child.content])
)
} else if (child.type === NodeTypes.IF) {
processIf(child, context)
ssrProcessIf(child, context)
} else if (child.type === NodeTypes.FOR) {
processFor(child, context)
ssrProcessFor(child, context)
}
}
}

View File

@@ -1,3 +1,49 @@
import { NodeTransform } from '@vue/compiler-dom'
import {
NodeTransform,
isSlotOutlet,
processSlotOutlet,
createCallExpression,
SlotOutletNode,
createFunctionExpression,
createBlockStatement
} from '@vue/compiler-dom'
import { SSR_RENDER_SLOT } from '../runtimeHelpers'
import {
SSRTransformContext,
createChildContext,
processChildren
} from '../ssrCodegenTransform'
export const ssrTransformSlotOutlet: NodeTransform = () => {}
export const ssrTransformSlotOutlet: NodeTransform = (node, context) => {
if (isSlotOutlet(node)) {
const { slotName, slotProps } = processSlotOutlet(node, context)
node.ssrCodegenNode = createCallExpression(
context.helper(SSR_RENDER_SLOT),
[
`_ctx.$slots`,
slotName,
slotProps || `{}`,
`null`, // fallback content placeholder.
`_push`,
`_parent`
]
)
}
}
export function ssrProcessSlotOutlet(
node: SlotOutletNode,
context: SSRTransformContext
) {
const renderCall = node.ssrCodegenNode!
// has fallback content
if (node.children.length) {
const childContext = createChildContext(context)
processChildren(node.children, childContext)
const fallbackRenderFn = createFunctionExpression([])
fallbackRenderFn.body = createBlockStatement(childContext.body)
// _renderSlot(slots, name, props, fallback, ...)
renderCall.arguments[3] = fallbackRenderFn
}
context.pushStatement(node.ssrCodegenNode!)
}

View File

@@ -1,7 +1,7 @@
import {
createStructuralDirectiveTransform,
ForNode,
processForNode,
processFor,
createCallExpression,
createFunctionExpression,
createForLoopParams,
@@ -18,12 +18,12 @@ import { SSR_RENDER_LIST } from '../runtimeHelpers'
// Plugin for the first transform pass, which simply constructs the AST node
export const ssrTransformFor = createStructuralDirectiveTransform(
'for',
processForNode
processFor
)
// This is called during the 2nd transform pass to construct the SSR-sepcific
// codegen nodes.
export function processFor(node: ForNode, context: SSRTransformContext) {
export function ssrProcessFor(node: ForNode, context: SSRTransformContext) {
const childContext = createChildContext(context)
const needFragmentWrapper =
node.children.length !== 1 || node.children[0].type !== NodeTypes.ELEMENT

View File

@@ -1,6 +1,6 @@
import {
createStructuralDirectiveTransform,
processIfBranches,
processIf,
IfNode,
createIfStatement,
createBlockStatement,
@@ -18,12 +18,12 @@ import {
// Plugin for the first transform pass, which simply constructs the AST node
export const ssrTransformIf = createStructuralDirectiveTransform(
/^(if|else|else-if)$/,
processIfBranches
processIf
)
// This is called during the 2nd transform pass to construct the SSR-sepcific
// codegen nodes.
export function processIf(node: IfNode, context: SSRTransformContext) {
export function ssrProcessIf(node: IfNode, context: SSRTransformContext) {
const [rootBranch] = node.branches
const ifStatement = createIfStatement(
rootBranch.condition!,