Просмотр исходного кода

refactor: adjust codegen for v-if on scoped slot

Evan You 7 лет назад
Родитель
Сommit
5851961ca3

+ 17 - 4
src/compiler/codegen/index.js

@@ -360,7 +360,10 @@ function genScopedSlots (
   slots: { [key: string]: ASTElement },
   slots: { [key: string]: ASTElement },
   state: CodegenState
   state: CodegenState
 ): string {
 ): string {
-  const hasDynamicKeys = Object.keys(slots).some(key => slots[key].slotTargetDynamic)
+  const hasDynamicKeys = Object.keys(slots).some(key => {
+    const slot = slots[key]
+    return slot.slotTargetDynamic || slot.if || slot.for
+  })
   return `scopedSlots:_u([${
   return `scopedSlots:_u([${
     Object.keys(slots).map(key => {
     Object.keys(slots).map(key => {
       return genScopedSlot(key, slots[key], state)
       return genScopedSlot(key, slots[key], state)
@@ -373,19 +376,29 @@ function genScopedSlot (
   el: ASTElement,
   el: ASTElement,
   state: CodegenState
   state: CodegenState
 ): string {
 ): string {
+  if (el.if && !el.ifProcessed) {
+    return genIfScopedSlot(key, el, state)
+  }
   if (el.for && !el.forProcessed) {
   if (el.for && !el.forProcessed) {
     return genForScopedSlot(key, el, state)
     return genForScopedSlot(key, el, state)
   }
   }
   const fn = `function(${String(el.slotScope)}){` +
   const fn = `function(${String(el.slotScope)}){` +
     `return ${el.tag === 'template'
     `return ${el.tag === 'template'
-      ? el.if
-        ? `(${el.if})?${genChildren(el, state) || 'undefined'}:undefined`
-        : genChildren(el, state) || 'undefined'
+      ? genChildren(el, state) || 'undefined'
       : genElement(el, state)
       : genElement(el, state)
     }}`
     }}`
   return `{key:${key},fn:${fn}}`
   return `{key:${key},fn:${fn}}`
 }
 }
 
 
+function genIfScopedSlot (
+  key: string,
+  el: any,
+  state: CodegenState
+): string {
+  el.ifProcessed = true
+  return `(${el.if})?${genScopedSlot(key, el, state)}:null`
+}
+
 function genForScopedSlot (
 function genForScopedSlot (
   key: string,
   key: string,
   el: any,
   el: any,

+ 1 - 1
src/core/instance/render-helpers/resolve-slots.js

@@ -59,7 +59,7 @@ export function resolveScopedSlots (
     const slot = fns[i]
     const slot = fns[i]
     if (Array.isArray(slot)) {
     if (Array.isArray(slot)) {
       resolveScopedSlots(slot, hasDynamicKeys, res)
       resolveScopedSlots(slot, hasDynamicKeys, res)
-    } else {
+    } else if (slot) {
       res[slot.key] = slot.fn
       res[slot.key] = slot.fn
     }
     }
   }
   }

+ 2 - 2
test/unit/modules/compiler/codegen.spec.js

@@ -239,11 +239,11 @@ describe('codegen', () => {
   it('generate scoped slot with multiline v-if', () => {
   it('generate scoped slot with multiline v-if', () => {
     assertCodegen(
     assertCodegen(
       '<foo><template v-if="\nshow\n" slot-scope="bar">{{ bar }}</template></foo>',
       '<foo><template v-if="\nshow\n" slot-scope="bar">{{ bar }}</template></foo>',
-      `with(this){return _c('foo',{scopedSlots:_u([{key:"default",fn:function(bar){return (\nshow\n)?[_v(_s(bar))]:undefined}}])})}`
+      `with(this){return _c('foo',{scopedSlots:_u([(\nshow\n)?{key:"default",fn:function(bar){return [_v(_s(bar))]}}:null],true)})}`
     )
     )
     assertCodegen(
     assertCodegen(
       '<foo><div v-if="\nshow\n" slot="foo" slot-scope="bar">{{ bar }}</div></foo>',
       '<foo><div v-if="\nshow\n" slot="foo" slot-scope="bar">{{ bar }}</div></foo>',
-      `with(this){return _c(\'foo\',{scopedSlots:_u([{key:"foo",fn:function(bar){return (\nshow\n)?_c(\'div\',{},[_v(_s(bar))]):_e()}}])})}`
+      `with(this){return _c(\'foo\',{scopedSlots:_u([(\nshow\n)?{key:"foo",fn:function(bar){return _c(\'div\',{},[_v(_s(bar))])}}:null],true)})}`
     )
     )
   })
   })