Vue 插槽slot和作用域插槽slot-scope

2019-12-18  本文已影响0人  全球顶尖伪极客

什么插槽

官网说明:

2.6.0中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性。新语法的由来可查阅这份 RFC

单个插槽|默认插槽 | 匿名插槽

父模板

<div class="parent">
     <h3>这里是父组件</h3>
    <alert-box>有bug发生</alert-box>
    <alert-box>有一个警告</alert-box>
    <alert-box></alert-box>
</div>

子组件
  Vue.component('alert-box', {
      template: `
        <div> <strong>ERROR:</strong>
        <slot>子组件插槽默认内容</slot>
    </div>
    `
    });
展示结果:
ERROR: 有bug发生
ERROR: 有一个警告
ERROR: 子组件插槽默认内容


<template>
    <div class="parent">
        <h3>这里是父组件</h3>
        <child>
            <h4>这里是子组件中插槽占位处要展示的内容</h4>
            <div class="tmpl">
              <span>菜单1</span>
              <span>菜单2</span> 
            </div>
        </child>
    </div>
</template>


子组件
<template>
    <div class="child">
        <h3>这里是子组件</h3>
        <slot></slot>
    </div>
</template>

具名插槽

父组件
<base-layout>
      <p slot='header'>标题信息</p>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <p slot='footer'>底部信息</p>
</base-layout>

子组件:
  Vue.component('base-layout', {
      template: `
      <div>
          有name的插槽可以在该组件中存在多次
          <header><slot name='header'></slot></header>
          <main> <slot></slot></main>
          <footer><slot name='footer'></slot></footer>
      </div>
      `
    });

展示结果:
标题信息
主要内容1
主要内容2
底部信息

作用域插槽 | 带数据的插槽

作用域插槽:在slot上面绑定数据。自 2.6.0 起有所更新。已废弃的使用 slot-scope特性的语法。官网介绍新版
slot-scope 声明了被接收的prop对象会作为 slotProps变量存在于 <template>作用域中。你可以像命名JavaScript函数参数一样随意命名 slotProps

 <fruit-list :list='list'>
      <template slot-scope='slotProps'>
        <strong v-if='slotProps.info.id==3' class="current">
          {{slotProps.info.name}}
        </strong>
      </template>
</fruit-list>
 Vue.component('fruit-list', {
      props: ['list'],
      template: `
     <div>
      <li :key='item.id' v-for='item in list'>
          <slot :info='item'>{{item.name}}</slot>
      </li>
     </div>
      `
});
var vm = new Vue({
      el: '#app',
      data: {
        list: [{
            id: '1',
            name: 'apple'
          }, {
            id: '2',
            name: 'orange'
          }, {
            id: '3',
            name: 'banana'
          }

        ]
      }
    });
结果:
apple
orange
banana
image.png

2.6.0+官网写法

将包含所有插槽prop的对象命名为 slotProps名字任意取。

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:

<!-- 无效,会导致警告 -->
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
  <template v-slot:other="otherSlotProps">
    slotProps is NOT available here
  </template>
</current-user>
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user

解构插槽Prop

function (slotProps) {
  // 插槽内容
}
<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>
重命名
<current-user v-slot="{ user: person }">
  {{ person.firstName }}
</current-user>
具名插槽

v-onv-bind一样,v-slot也有缩写,即把参数之前的所有内容(v-slot:)替换为字符#。例如v-slot:header可以被重写为 #header

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
  {{ user.firstName }}
</current-user>
<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>

参考链接

上一篇下一篇

猜你喜欢

热点阅读