【Vue.js】 插槽通信——具名插槽通信

前景

下面的父子组件代码仍然在Vue.js演练平台直接运行

基本语法

在子组件中定义插槽

<!-- Category.vue -->
<slot name="插槽名称">默认内容</slot>
  • 使用 <slot> 标签定义插槽位置
  • 通过 name 属性给插槽命名
  • 标签内部内容为默认内容(当父组件不提供内容时显示)

在父组件中使用插槽

<!-- App.vue -->
<Category>
  <template #插槽名称>
    <!-- 要插入的内容 -->
  </template>
</Category>
  • 使用 <template> 标签包裹要插入的内容
  • 使用 v-slot:插槽名称 或简写 #插槽名称 指定要插入的插槽

命名规则

  • 插槽名称可以是任意有效的JavaScript标识符
  • 名称区分大小写

默认内容

  • 当父组件不提供插槽内容时,显示子组件中定义的默认内容
  • 提供内容时,默认内容会被覆盖

使用建议

  1. 为插槽取有意义的名称,提高代码可读性
  2. 合理使用默认内容,增强组件的健壮性
  3. 可以使用多个 <template> 块为同一个组件提供不同的插槽内容
  4. 简写语法 #插槽名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)。

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Issac-Clarke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值