山东齐鲁工惠
54.46M · 2026-02-05
在组件化开发中,插槽 (Slot) 是实现内容分发(Content Distribution)的核心机制。它允许我们将组件的“外壳”与“内容”解耦,让组件具备极高的扩展性。
插槽是子组件提供给父组件的 “占位符” ,用 <slot></slot> 标签表示。父组件传递的任何模板代码(HTML、组件等)都会替换子组件中的 <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>
当子组件需要多个占位符时,通过 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>版权信息 © 2026</p>
</template>
</LayoutComponent>
</template>
<script setup lang="ts">
import LayoutComponent from './LayoutComponent.vue';
</script>
核心价值: “子传父” 的特殊形式。子组件将内部数据绑定在 <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)需要自定义时使用。 |
| 作用域插槽 | 需要根据子组件的内部数据来决定父组件渲染样式的场景(如列表展示)。 |