Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自于 Web Components 规范草案,将 元素作为承载分发内容的出口。

简而言之,slot 就是用来为子组件分发渲染内容的,具有作用域的 component,又名插槽。

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

使用方法

官方文档例子

组件:

  1. <div class="container">
  2. <header>
  3. <!-- 我们希望把页头放这里 -->
  4. </header>
  5. <main>
  6. <!-- 我们希望把主要内容放这里 -->
  7. </main>
  8. <footer>
  9. <!-- 我们希望把页脚放这里 -->
  10. </footer>
  11. </div


我们可以通过 元素的 name 属性,定义插槽。

  1. <div class="container">
  2. <header>
  3. <slot name="header"></slot>
  4. </header>
  5. <main>
  6. <slot></slot>
  7. </main>
  8. <footer>
  9. <slot name="footer"></slot>
  10. </footer>
  11. </div

注意⚠️:如果 slot 不带 name,则默认为 default 值。
向具名插槽分发内容时,我们可以在一个 元素上使用 v-slot 指令,并以参数的形式提供其名称:

  1. <base-layout>
  2. <template v-slot:header>
  3. <h1>Here might be a page title</h1>
  4. </template>
  5. <p>A paragraph for the main content.</p>
  6. <p>And another one.</p>
  7. <template v-slot:footer>
  8. <p>Here's some contact info</p>
  9. </template>
  10. </base-layout>

渲染结果:

  1. <div class="container">
  2. <header>
  3. <h1>Here might be a page title</h1>
  4. </header>
  5. <main>
  6. <p>A paragraph for the main content.</p>
  7. <p>And another one.</p>
  8. </main>
  9. <footer>
  10. <p>Here's some contact info</p>
  11. </footer>
  12. </div>

注意⚠️:v-slot 只能添加在一个 <template> 上。

作用域

为了在 slot 中可以使用外部的数据,可以将数据作为 元素的一个特性绑定:

  1. <span>
  2. <slot v-bind:user="user">
  3. {{ user.lastName }}
  4. </slot>
  5. </span>

动态插槽名

2.6.0 新增

  1. <base-layout>
  2. <template v-slot:[dynamicSlotName]>
  3. ...
  4. </template>
  5. </base-layout>