前言

在组件化开发中,插槽 (Slot) 是实现内容分发(Content Distribution)的核心机制。它允许我们将组件的“外壳”与“内容”解耦,让组件具备极高的扩展性。

一、 什么是插槽?

插槽是子组件提供给父组件的 “占位符” ,用 <slot></slot> 标签表示。父组件传递的任何模板代码(HTML、组件等)都会替换子组件中的 <slot> 标签。


二、 插槽的三大类型

1. 默认插槽 (Default Slot)

最基础的插槽,不需要定义 name 属性。

  • 特点:一个子组件通常只建议使用一个默认插槽。

示例:

 <!-- 子组件 -->
  <template>
    <div class="card">
      <div class="card-title">通用卡片标题</div>
      <div class="card-content">
        <slot> 这里是默认的填充文本 </slot>
      </div>
    </div>
  </template>
 <!-- 父组件 -->
  <template>
    <div class="app">
      <MyCard> 这是我传递给卡片的具体内容。 </MyCard>
    </div>
  </template>

2. 具名插槽 (Named Slots)

当子组件需要多个占位符时,通过 name 属性来区分。

  • 语法糖v-slot:header 可以简写为 #header

示例:

 <!-- 子组件:LayoutComponent.vue -->
<template>
  <div class="layout">
    <header class="header">
      <slot name="header"></slot>
    </header>
    
    <main class="content">
      <slot></slot> 
    </main>
    
    <footer class="footer">
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<script setup lang="ts">
 <!-- Vue 3 Composition API 模式下,逻辑部分可以保持简洁 -->
</script>
 <!-- 父组件使用示例 -->
<template>
  <LayoutComponent>
    <template #header>
      <h1>页面标题</h1>
      <nav>导航菜单</nav>
    </template>
    
    <p>这是主体内容,将填充到默认插槽中...</p>
    
    <template #footer>
      <p>版权信息 &copy; 2026</p>
    </template>
  </LayoutComponent>
</template>

<script setup lang="ts">
import LayoutComponent from './LayoutComponent.vue';
</script>

3. 作用域插槽 (Scoped Slots)

核心价值“子传父” 的特殊形式。子组件将内部数据绑定在 <slot> 上,父组件在填充内容时可以接收并使用这些数据。

示例:

 <!-- 子组件:`UserList.vue` -->
<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      <slot :user="user" :index="user.id">
        {{ user.name }}
      </slot>
    </li>
  </ul>
</template>

<script setup lang="ts">
interface User {
  id: number;
  name: string;
  role: string;
}

const users: User[] = [
  { id: 1, name: '张三', role: '管理员' },
  { id: 2, name: '李四', role: '开发者' }
];
</script>
 <!-- 父组件使用示例 -->
<template>
  <UserList>
    <template #default="{ user }">
      <span :style="{ color: user.role === '管理员' ? 'red' : 'blue' }">
        {{ user.name }} - 【{{ user.role }}】
      </span>
    </template>
  </UserList>
</template>

三、 补充:插槽的默认内容

在子组件中,你可以在 <slot> 标签内部放置内容。如果父组件没有提供任何插槽内容,则会渲染这些“后备内容”;如果提供了,则会被覆盖。

<slot>这是如果没有内容时显示的默认文本</slot>

四、 总结:如何选择插槽?

插槽类型使用场景
默认插槽组件只有一个扩展点时使用。
具名插槽组件有多个固定区域(如 Header/Main/Footer)需要自定义时使用。
作用域插槽需要根据子组件的内部数据来决定父组件渲染样式的场景(如列表展示)。
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com