diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index ac8f89c4..d35530d6 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -229,6 +229,7 @@ export interface ForNode extends Node { valueAlias: ExpressionNode | undefined keyAlias: ExpressionNode | undefined objectIndexAlias: ExpressionNode | undefined + parseResult: ForParseResult children: TemplateChildNode[] codegenNode?: ForCodegenNode } @@ -619,7 +620,7 @@ export function createCallExpression( export function createFunctionExpression( params: FunctionExpression['params'], - returns: FunctionExpression['returns'], + returns: FunctionExpression['returns'] = undefined, newline: boolean = false, isSlot: boolean = false, loc: SourceLocation = locStub diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index b794f3f8..726ea38a 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -439,8 +439,12 @@ function genNodeList( genNode(node, context) } if (i < nodes.length - 1) { - comma && push(',') - multilines && newline() + if (multilines) { + comma && push(',') + newline() + } else { + comma && push(', ') + } } } } diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts index 6b63067d..c9c80e57 100644 --- a/packages/compiler-core/src/index.ts +++ b/packages/compiler-core/src/index.ts @@ -33,7 +33,7 @@ export { transformOn } from './transforms/vOn' // exported for compiler-ssr export { processIfBranches } from './transforms/vIf' -export { processForNode } from './transforms/vFor' +export { processForNode, createForLoopParams } from './transforms/vFor' export { transformExpression, processExpression diff --git a/packages/compiler-core/src/transforms/vFor.ts b/packages/compiler-core/src/transforms/vFor.ts index 077101ab..9081cb3f 100644 --- a/packages/compiler-core/src/transforms/vFor.ts +++ b/packages/compiler-core/src/transforms/vFor.ts @@ -45,7 +45,7 @@ export const transformFor = createStructuralDirectiveTransform( 'for', (node, dir, context) => { const { helper } = context - return processForNode(node, dir, context, (forNode, parseResult) => { + return processForNode(node, dir, context, forNode => { // create the loop render function expression now, and add the // iterator on exit after all children have been traversed const renderExp = createCallExpression(helper(RENDER_LIST), [ @@ -122,7 +122,7 @@ export const transformFor = createStructuralDirectiveTransform( renderExp.arguments.push( createFunctionExpression( - createForLoopParams(parseResult), + createForLoopParams(forNode.parseResult), childBlock, true /* force newline */ ) @@ -137,10 +137,7 @@ export function processForNode( node: ElementNode, dir: DirectiveNode, context: TransformContext, - processCodegen?: ( - forNode: ForNode, - parseResult: ForParseResult - ) => (() => void) | undefined + processCodegen?: (forNode: ForNode) => (() => void) | undefined ) { if (!dir.exp) { context.onError( @@ -173,6 +170,7 @@ export function processForNode( valueAlias: value, keyAlias: key, objectIndexAlias: index, + parseResult, children: node.tagType === ElementTypes.TEMPLATE ? node.children : [node] } @@ -188,7 +186,7 @@ export function processForNode( index && addIdentifiers(index) } - const onExit = processCodegen && processCodegen(forNode, parseResult) + const onExit = processCodegen && processCodegen(forNode) return () => { scopes.vFor-- diff --git a/packages/compiler-ssr/src/transforms/ssrVFor.ts b/packages/compiler-ssr/src/transforms/ssrVFor.ts index 49f8e998..8e03edf3 100644 --- a/packages/compiler-ssr/src/transforms/ssrVFor.ts +++ b/packages/compiler-ssr/src/transforms/ssrVFor.ts @@ -1,9 +1,18 @@ import { createStructuralDirectiveTransform, ForNode, - processForNode + processForNode, + createCallExpression, + createFunctionExpression, + createForLoopParams, + createBlockStatement } from '@vue/compiler-dom' -import { SSRTransformContext } from '../ssrCodegenTransform' +import { + SSRTransformContext, + createChildContext, + processChildren +} from '../ssrCodegenTransform' +import { SSR_RENDER_LIST } from '../runtimeHelpers' // Plugin for the first transform pass, which simply constructs the AST node export const ssrTransformFor = createStructuralDirectiveTransform( @@ -13,4 +22,17 @@ export const ssrTransformFor = createStructuralDirectiveTransform( // This is called during the 2nd transform pass to construct the SSR-sepcific // codegen nodes. -export function processFor(node: ForNode, context: SSRTransformContext) {} +export function processFor(node: ForNode, context: SSRTransformContext) { + const renderLoop = createFunctionExpression( + createForLoopParams(node.parseResult) + ) + const childContext = createChildContext(context) + processChildren(node.children, childContext) + renderLoop.body = createBlockStatement(childContext.body) + context.pushStatement( + createCallExpression(context.helper(SSR_RENDER_LIST), [ + node.source, + renderLoop + ]) + ) +}