Parcourir la source

wip: codegen for scoped slots

Evan You il y a 9 ans
Parent
commit
3575ff4a88
3 fichiers modifiés avec 42 ajouts et 15 suppressions
  1. 1 0
      flow/compiler.js
  2. 38 14
      src/compiler/codegen/index.js
  3. 3 1
      src/compiler/parser/index.js

+ 1 - 0
flow/compiler.js

@@ -87,6 +87,7 @@ declare type ASTElement = {
   transitionMode?: string | null;
   slotName?: ?string;
   slotTarget?: ?string;
+  scopedSlots?: { [name: string]: ASTElement };
 
   ref?: string;
   refInFor?: boolean;

+ 38 - 14
src/compiler/codegen/index.js

@@ -182,20 +182,11 @@ function genData (el: ASTElement): string {
   }
   // inline-template
   if (el.inlineTemplate) {
-    const ast = el.children[0]
-    if (process.env.NODE_ENV !== 'production' && (
-      el.children.length > 1 || ast.type !== 1
-    )) {
-      warn('Inline-template components must have exactly one child element.')
-    }
-    if (ast.type === 1) {
-      const inlineRenderFns = generate(ast, currentOptions)
-      data += `inlineTemplate:{render:function(){${
-        inlineRenderFns.render
-      }},staticRenderFns:[${
-        inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',')
-      }]}`
-    }
+    data += `${genInlineTemplate(el)},`
+  }
+  // scoped slots
+  if (el.scopedSlots) {
+    data += `${genScopedSlots(el.scopedSlots)},`
   }
   data = data.replace(/,$/, '') + '}'
   // v-bind data wrap
@@ -236,6 +227,39 @@ function genDirectives (el: ASTElement): string | void {
   }
 }
 
+function genInlineTemplate (el) {
+  const ast = el.children[0]
+  if (process.env.NODE_ENV !== 'production' && (
+    el.children.length > 1 || ast.type !== 1
+  )) {
+    warn('Inline-template components must have exactly one child element.')
+  }
+  if (ast.type === 1) {
+    const inlineRenderFns = generate(ast, currentOptions)
+    return `inlineTemplate:{render:function(){${
+      inlineRenderFns.render
+    }},staticRenderFns:[${
+      inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',')
+    }]}`
+  } else {
+    return ''
+  }
+}
+
+function genScopedSlots (slots) {
+  return `scopedSlots:{${
+    Object.keys(slots).map(key => genScopedSlot(key, slots[key])).join(',')
+  }}`
+}
+
+function genScopedSlot (key: string, el: ASTElement) {
+  return `${key}:function(${String(el.attrsMap.scope)}){` +
+    `return ${el.tag === 'template'
+      ? genChildren(el) || 'void 0'
+      : genElement(el)
+  }}`
+}
+
 function genChildren (el: ASTElement): string | void {
   if (el.children.length) {
     return '[' + el.children.map(genNode).join(',') + ']'

+ 3 - 1
src/compiler/parser/index.js

@@ -167,8 +167,10 @@ export function parse (
         }
       }
       if (currentParent && !element.forbidden) {
-        if (element.else) {
+        if (element.else) { // else block
           processElse(element, currentParent)
+        } else if (element.slotTarget && element.attrsMap.scope) { // scoped slot
+          (currentParent.scopedSlots || (currentParent.scopedSlots = {}))[element.slotTarget] = element
         } else {
           currentParent.children.push(element)
           element.parent = currentParent