소스 검색

wip(ssr): v-for

Evan You 6 년 전
부모
커밋
93c37b94f2

+ 2 - 1
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<T extends CallExpression['callee']>(
 
 export function createFunctionExpression(
   params: FunctionExpression['params'],
-  returns: FunctionExpression['returns'],
+  returns: FunctionExpression['returns'] = undefined,
   newline: boolean = false,
   isSlot: boolean = false,
   loc: SourceLocation = locStub

+ 6 - 2
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(', ')
+      }
     }
   }
 }

+ 1 - 1
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

+ 5 - 7
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--

+ 25 - 3
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
+    ])
+  )
+}