vue的插槽详细讲解

102 阅读2分钟

在Vue中,插槽(Slot)是一种强大的内容分发机制,允许父组件向子组件传递模板片段,从而实现更灵活的组件复用。根据使用场景和功能需求,插槽可分为以下三种类型:


1. 匿名插槽(默认插槽)

作用:用于接收父组件传递的默认内容,当子组件只需要一个插槽时使用。

子组件定义

<!-- ChildComponent.vue -->
<template>
  <div class="child">
    <slot>默认内容(当父组件未提供时显示)</slot>
  </div>
</template>

父组件使用

<ChildComponent>
  <p>父组件传递的内容</p>
</ChildComponent>

特点

  • 父组件内容会替换子组件中的<slot>标签。
  • 若父组件未提供内容,显示子组件<slot>内的默认内容。

2. 具名插槽

作用:当子组件有多个插槽位置时,通过命名区分不同插槽。

子组件定义

<!-- LayoutComponent.vue -->
<template>
  <div class="layout">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot> <!-- 匿名插槽,默认名为default -->
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

父组件使用

<LayoutComponent>
  <!-- 匿名插槽内容(对应默认插槽) -->
  <template v-slot:default>
    <p>主内容区域</p>
  </template>

  <!-- 具名插槽内容 -->
  <template v-slot:header>
    <h1>页面标题</h1>
  </template>

  <template v-slot:footer>
    <p>版权信息</p>
  </template>
</LayoutComponent>

语法注意

  • Vue 2.6+ 使用v-slot:name,可简写为#name(如#header)。
  • 匿名插槽的隐式名为defaultv-slot:default可省略。

3. 作用域插槽

作用:允许子组件向父组件传递数据,父组件根据数据动态渲染内容。

子组件定义

<!-- TableComponent.vue -->
<template>
  <table>
    <tr v-for="(item, index) in items" :key="index">
      <td>
        <!-- 传递数据给父组件 -->
        <slot :item="item" :index="index"></slot>
      </td>
    </tr>
  </table>
</template>

<script>
export default {
  props: ['items']
}
</script>

父组件使用

<TableComponent :items="userList">
  <template v-slot:default="slotProps">
    <!-- 使用子组件传递的数据 -->
    <span>{{ slotProps.item.name }} (ID: {{ slotProps.index }})</span>
  </template>
</TableComponent>

语法简化

  • 对象解构:
    <template v-slot:default="{ item, index }">
      <span>{{ item.name }} ({{ index }})</span>
    </template>
    

版本差异与最佳实践

Vue 2 vs Vue 3

  • Vue 2
    • 旧语法:slot="name"slot-scope="props"
    • 推荐升级到v-slot语法(2.6+支持)。
  • Vue 3
    • 完全支持v-slot,移除旧语法。
    • 作用域插槽数据传递更直观。

最佳实践

  1. 明确命名:多插槽组件务必使用具名插槽,提升可读性。
  2. 作用域隔离:通过作用域插槽减少父子组件耦合,增强复用性。
  3. 动态插槽名(Vue 2.6+/3):
    <template v-slot:[dynamicSlotName]>
      <!-- 内容 -->
    </template>
    

实际应用场景

  1. 通用布局组件:通过具名插槽定义页面的Header、Main、Footer。
  2. 数据驱动组件:如表单、表格使用作用域插槽,允许自定义渲染逻辑。
  3. UI库组件:如Element UI的el-table通过作用域插槽暴露行数据。

总结

  • 匿名插槽:基础内容分发,适合单一内容占位。
  • 具名插槽:多插槽场景,明确内容位置。
  • 作用域插槽:子向父传递数据,实现动态渲染。