Vue3 | 组件化开发---组件插槽与通信

今天依旧对Vue进行学习与回顾 ,重点复盘了组件插槽 的核心用法,同时简单回顾了"兄弟"组件通信的关键方式,整理成笔记方便后续复习巩固以及希望帮助到正在深耕于vue的你们~

一、兄弟组件通信

Vue中兄弟组件无法直接传递数据,今天介绍两种简单的实现方式:

1. 父组件中转(Emits + Props)

兄弟组件1通过**defineEmits** 触发自定义事件传数据,父组件接收后,再通过**Props**把数据传递给兄弟组件2。

代码示例:
TypeScript 复制代码
<!-- 兄弟1:触发事件传值 -->
<script setup lang="ts">
const emit = defineEmits(["rev"])
function sendB2(){
    emit("rev","hello") // 触发事件并传递数据
}
</script>

<!-- 兄弟2:接收父组件Props -->
<script setup lang="ts">
interface p{ msg:string }
const props = defineProps<p>()
</script>
<template>{{ props.msg }}</template>

<!-- 父组件:接受兄弟1的值并发送给兄弟2 -->
<script setup lang="ts">
import { ref } from "vue";
import b1 from "./study_tree/16.兄弟组件通信/18.bro1.vue"
import b2 from "./study_tree/16.兄弟组件通信/18.bro2.vue"
const b1Msg = ref("")
function receive(data:string){
  b1Msg.value = data
}
</script>

<template>
  <div>
    <b1 @rev="receive"></b1>
    <b2 :msg="b1Msg"></b2>
  </div>
</template>

2. Event Bus 事件总线

兄弟 1 通过**emit** 发布事件,兄弟 2 通过**on**监听事件,无需父组件介入。

代码示例:
TypeScript 复制代码
<!-- 兄弟1:发布事件 -->
<script setup lang="ts">
import bus from '@/until/bus';
import { ref } from 'vue';
const data = ref("")
function send(data:string){
    bus.emit("transfer",data)
}
</script>

<!-- 兄弟2:监听事件 -->
<script setup lang="ts">
import bus from "@/until/bus"
import { ref } from "vue";
const result = ref("")
bus.on("transfer",(data:string)=>{
    result.value = data
})
</script>

二、组件插槽(核心重点)

插槽是Vue实现组件内容灵活分发的核心能力,允许父组件向子组件传递任意结构的内容,结合实操代码拆解 3 类核心插槽:

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

核心逻辑 :子组件用**<slot>**标记占位(可设默认值),父组件使用子组件时,直接写入内容即可替换默认值。

子组件代码:
TypeScript 复制代码
<script setup lang="ts"></script>
<template>
    <div>这是组件的内容 下面是需要替换的内容</div>
    <!-- 插槽占位,设置默认值 -->
    <div><slot>我是要被替换的</slot></div>
</template>
父组件使用:
TypeScript 复制代码
<template>
  <Slot1>111</Slot1> <!-- 替换插槽默认值为"111" -->
</template>
说明
  • 父组件写入的内容会完全替换**<slot>**内的默认值;
  • 若父组件未传内容,会显示插槽默认值。

2. 具名插槽

核心逻辑 :子组件给**<slot>** 加**name** 属性命名,父组件通过**<template #插槽名>**精准替换对应插槽。

子组件代码:
TypeScript 复制代码
<script setup lang="ts"></script>
<template>
    具名插槽
    <div class="item head">
        <slot name="head"></slot> <!-- 头部命名插槽 -->
    </div>
    <div class="item body">
        <slot></slot> <!-- 默认插槽(等价于name="default") -->
    </div>
    <div class="item footer">
        <slot name="footer"></slot> <!-- 底部命名插槽 -->
    </div>
</template>
<style scoped>
.item{ width: 200px; height: 50px; }
.head{ background-color: #282828; }
.body{ background-color: #e5bdbd; }
.footer{ background-color: #796f6f; }
div{ color: white; }
</style>
父组件使用:
TypeScript 复制代码
<template>
  <Slot2>
    123 <!-- 替换默认插槽(body区域) -->
    <template #head>head</template> <!-- 替换head插槽 -->
    <template #footer>footer</template> <!-- 替换footer插槽 -->
  </Slot2>
</template>
说明
  • #插槽名 是**v-slot:插槽名**的简写,是 Vue3 推荐的简洁语法;
  • 未命名的**<slot>** 默认对应**name="default"**,父组件直接写内容即可替换。

3. 作用域插槽

核心逻辑 :子组件向插槽传递数据(通过**v-bind**绑定),父组件接收后自定义渲染逻辑,解决 "子组件数据、父组件决定渲染样式 / 结构" 的场景。

子组件代码:
TypeScript 复制代码
<script setup lang="ts">
import { ref } from 'vue';
// 子组件内部数据
const list = ref([
    {"name":"Liu",age:20},
    {"name":"He",age:18}
])
</script>
<template>
    作用域插槽
    <div class="ul">
        <div class="item" v-for="item in list">
            <!-- 向插槽传递数据:v-bind:data = 子组件数据 -->
            <slot :data="item">
                <!-- 插槽默认渲染逻辑(父组件未自定义时生效) -->
                <span class="name">name:{{ item.name }}</span>
                <span>age:{{ item.age }}</span>
            </slot>
        </div>
    </div>
</template>
<style scoped>
/* 仅作用于插槽默认渲染内容 */
.name{ color: red; }
</style>
父组件使用
TypeScript 复制代码
<template>
  <Slot3>
    <!-- 接收子组件传递的插槽数据:#default="自定义对象名" -->
    <template #default="slotdata">
      <div>
        <i class="name">{{ slotdata.data.name }}</i>
      </div>
    </template>
  </Slot3>
</template>
<style scoped>
/* 父组件自定义样式覆盖默认样式 */
.name{ color: aqua; }
</style>
说明
  • 子组件传值:通过**v-bind:xxx="数据"**向插槽暴露数据(可绑定多个属性);
  • 父组件接收:#default="自定义对象名",对象内包含子组件传递的所有数据;
  • 样式规则:子组件**scoped**样式仅作用于插槽默认内容,父组件自定义内容的样式由父组件控制。

三、小结

  1. 核心价值:让组件结构更灵活,父组件可按需定制子组件的部分内容,无需重复封装子组件;
  2. 注意点:Vue3 中插槽语法更简洁(#简写),结合 TypeScript 可提升代码类型安全性。
  3. 选型技巧:
  • 单区域内容替换 → 默认插槽;
  • 多区域内容替换 → 具名插槽;
  • 子数据父渲染 → 作用域插槽;

看完赶紧去敲一敲,动动手才是真理

相关推荐
念何架构之路几秒前
zap扩展生态与总结
java·前端·数据库
独孤九剑打醒他16 分钟前
【原创开源】【概念设计】源 - 栅 - 漏 - 栅 - 源 横向双栅 MOS,低压交流多值逻辑芯片探索
前端·其他·架构·开源·硬件工程
mantou1321 小时前
我给 AI Agent 做了个「油猴」:让 Claude Code / Codex 直接用你已登录的浏览器
前端·javascript·后端
默_笙1 小时前
🍕 一个主编、三个工种、两本手册:搭一支 AI 调研队
前端·javascript
纸片人1 小时前
Blender 建模 + Three.js 展示:和 AI 一起做一个光储充超充站数字孪生大屏
前端
智能直播1 小时前
网络RTMP拉流不卡顿、声音不同步?一文讲透缓冲区、时间戳与MEDAI V2实战调优
前端
第七页独白1 小时前
汽车零件厂如何通过 QMS 真正落地 IATF 16949——QMS软件系统:品质检验-内审稽核-8d客诉管理:全星质量管理软件系统
java·前端·数据库
纸片人1 小时前
只用 three.js + OpenStreetMap,手搓一个「成都城市 3D」数据大屏
前端
星若生辉1 小时前
Hugo 静态站点搭建|从本地调试到上线部署实操指南
前端
沐浴露z1 小时前
Agent 响应延迟过高?从工具治理角度提供两条思路
前端·网络