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. 选型技巧:
  • 单区域内容替换 → 默认插槽;
  • 多区域内容替换 → 具名插槽;
  • 子数据父渲染 → 作用域插槽;

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

相关推荐
CodeGuru4 小时前
UniApp Vue3 生成海报并分享到朋友圈
前端
三原4 小时前
附源码:三原管理系统新增俩种常用布局
java·前端·vue.js
DyLatte4 小时前
当我想把所有角色都做好时,就开始内耗了
前端·后端·程序员
a1117764 小时前
汽车展厅项目 开源项目 ThreeJS
前端·开源·html
你的不安4 小时前
GEE中getInfo()
javascript·云计算·gee
阳火锅4 小时前
Element / AntD 官方都没做好的功能,被这个开源小插件搞定了!
前端·vue.js·面试
大阳光男孩4 小时前
Uniapp+Vue3树形选择器
前端·javascript·uni-app
绝世唐门三哥4 小时前
uniapp系列-uniappp都有哪些生命周期?
vue.js·小程序·uniapp
沙振宇4 小时前
【Web】使用Vue3+PlayCanvas开发3D游戏(九)纹理视觉效果
前端·游戏·3d·纹理