前景
下面的父子组件代码仍然在Vue.js演练平台直接运行
基本语法
在子组件中定义插槽
<!-- Category.vue -->
<slot name="插槽名称">默认内容</slot>
- 使用
<slot>标签定义插槽位置 - 通过
name属性给插槽命名 - 标签内部内容为默认内容(当父组件不提供内容时显示)
在父组件中使用插槽
<!-- App.vue -->
<Category>
<template #插槽名称>
<!-- 要插入的内容 -->
</template>
</Category>
- 使用
<template>标签包裹要插入的内容 - 使用
v-slot:插槽名称或简写#插槽名称指定要插入的插槽
命名规则
- 插槽名称可以是任意有效的JavaScript标识符
- 名称区分大小写
默认内容
- 当父组件不提供插槽内容时,显示子组件中定义的默认内容
- 提供内容时,默认内容会被覆盖
使用建议
- 为插槽取有意义的名称,提高代码可读性
- 合理使用默认内容,增强组件的健壮性
- 可以使用多个
<template>块为同一个组件提供不同的插槽内容 - 简写语法
#插槽名比v-slot:插槽名更简洁
具名插槽的本质:父组件向子组件「精准投喂」内容
当子组件(Category) 需要在多个位置接收不同的父组件内容,并且希望结构化地控制内容的插入位置时使用。
具名插槽可以解决以下场景组件复用的痛点:
具体实例
父组件 index.vue
<template>
<div class="parent-container">
<h3>父组件</h3>
<div class="categories-container">
<Category class="category-item">
<template #s2>
<div class="content-box">
<h4>士兵类型</h4>
<ul>
<li v-for="s in sodierTypes" :key="s.id">{{ s.name }}</li>
</ul>
</div>
</template>
</Category>
<Category class="category-item">
<template #s1>
<div class="content-box">
<h4>风景图片</h4>
<img :src="img_url" alt="风景图片" class="responsive-image" />
</div>
</template>
</Category>
<Category class="category-item">
<template #s3>
<div class="content-box">
<h4>视频展示</h4>
<video :src="v_url1" controls class="responsive-video" />
</div>
</template>
</Category>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import Category from './Category.vue';
const v_url1 = ref('https://vod.v.jstv.com/2025/02/04/JSTV_JSGGNEW_1738669283837_9IgYA02_1378.mp4');
const img_url = ref('https://youimg1.c-ctrip.com/target/100n0p000000fnj3g0396.jpg');
const sodierTypes = reactive([
{ id: 'zyb', name: '支援兵' },
{ id: 'tjb', name: '突击兵' },
{ id: 'ylb', name: '医疗兵' },
{ id: 'zcb', name: '侦察兵' }
]);
</script>
<style scoped>
.parent-container {
padding: 20px;
}.categories-container {
display: flex;
gap: 20px;
margin-top: 20px;
flex-wrap: wrap;
}.category-item {
flex: 1;
min-width: 300px;
border: 1px solid #eee;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}.content-box {
display: flex;
flex-direction: column;
gap: 10px;
}.responsive-image {
max-width: 100%;
height: auto;
border-radius: 4px;}
.responsive-video {
width: 100%;
border-radius: 4px;
}h4 {
margin: 0 0 10px 0;
color: #333;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}li {
padding: 5px 0;
border-bottom: 1px solid #f0f0f0;
}li:last-child {
border-bottom: none;
}
</style>
子组件 Category.vue
父组件在template标签中定义的插槽名,子组件使用 name属性与父组件对应插槽绑定。
<template>
<div>
<slot name="s1"></slot>
<slot name="s2"></slot>
<slot name="s3"></slot>
</div>
</template>
<script setup lang="ts" name="Category">
</script>
作用:定义了三个具名插槽(s1、s2、s3),作为内容占位符。
| 特点 | 实现效果 |
|---|---|
| 内容精准投放 | 父组件通过 #s1、#s2、#s3 将不同内容插入子组件的对应位置。 |
| 组件高度复用 | 同一个 Category 组件通过插槽展示完全不同的内容(列表、图片、视频)。 |
| 结构清晰 | 子组件负责布局框架,父组件决定具体内容,职责分离。 |
| 灵活组合 | 父组件可以只填充部分插槽(例如仅用 s1 和 s2,忽略 s3)。 |
效果


1万+

被折叠的 条评论
为什么被折叠?



