插槽

Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 [Web Components](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md) 规范草案,将元素作为承载分发内容的出口。

插槽类型

匿名插槽(默认插槽)

没有命名默认只有一个。

  1. // 子组件
  2. <button type="submit">
  3. <slot>Submit</slot> // Submit作为默认值
  4. </button>
  5. <submit-button></submit-button> // 渲染出默认值Submit
  6. <submit-button>
  7. Save // 替换默认值,渲染出Save
  8. </submit-button>

具名插槽

与匿名插槽对应,slot标签带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>
    一个不带 name<slot> 出口会带有隐含的名字“default”。

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 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. <span>
    2. <slot v-bind:user="user">
    3. {{ user.lastName }}
    4. </slot>
    5. </span>
  • 父组件

    1. <current-user>
    2. <template v-slot:default="slotProps">
    3. <template scope="slotProps"> // 另一种写法
    4. {{ slotProps.user.firstName }}
    5. </template>
    6. </current-user>