Bladeren bron

fix: restore slot-scope + v-if behavior

fix #9422
Evan You 7 jaren geleden
bovenliggende
commit
44a4ca33b9

+ 5 - 2
src/compiler/codegen/index.js

@@ -375,7 +375,8 @@ function genScopedSlot (
   el: ASTElement,
   state: CodegenState
 ): string {
-  if (el.if && !el.ifProcessed) {
+  const isLegacySyntax = el.attrsMap['slot-scope']
+  if (el.if && !el.ifProcessed && !isLegacySyntax) {
     return genIf(el, state, genScopedSlot, `null`)
   }
   if (el.for && !el.forProcessed) {
@@ -383,7 +384,9 @@ function genScopedSlot (
   }
   const fn = `function(${String(el.slotScope)}){` +
     `return ${el.tag === 'template'
-      ? genChildren(el, state) || 'undefined'
+      ? el.if && isLegacySyntax
+        ? `(${el.if})?${genChildren(el, state) || 'undefined'}:undefined`
+        : genChildren(el, state) || 'undefined'
       : genElement(el, state)
     }}`
   return `{key:${el.slotTarget || `"default"`},fn:${fn}}`

+ 19 - 0
test/unit/features/component/component-scoped-slot.spec.js

@@ -650,6 +650,25 @@ describe('Component scoped slot', () => {
     }).then(done)
   })
 
+  // #9422
+  // the behavior of the new syntax is slightly different.
+  it('scoped slot v-if using slot-scope value', () => {
+    const Child = {
+      template: '<div><slot value="foo"/></div>',
+    }
+    const vm = new Vue({
+      components: { Child },
+      template: `
+        <child>
+          <template slot-scope="{ value }" v-if="value">
+            foo {{ value }}
+          </template>
+        </child>
+      `
+    }).$mount()
+    expect(vm.$el.textContent).toMatch(`foo foo`)
+  })
+
   // 2.6 new slot syntax
   describe('v-slot syntax', () => {
     const Foo = {

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

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