【Vue】组件通信(Props/Emit、EventBus、Provide/Inject)

在这里插入图片描述

个人主页:Guiat
归属专栏:Vue

在这里插入图片描述

文章目录

  • 1. Props/Emit 父子组件通信
    • 1.1 Props 向下传递数据
    • 1.2 Emit 向上传递事件
  • 2. EventBus 跨组件通信
    • 2.1 创建事件总线
    • 2.2 使用事件总线
    • 2.3 EventBus 优缺点
  • 3. Provide/Inject 深层组件通信
    • 3.1 基本使用
    • 3.2 响应式处理
    • 3.3 Provide/Inject 优缺点
  • 4. 各通信方式对比与选择
  • 5. 最佳实践建议

正文

1. Props/Emit 父子组件通信

1.1 Props 向下传递数据

Props 是 Vue 中最基本的组件通信方式,用于父组件向子组件传递数据。

// 子组件定义
export default {name: 'ChildComponent',props: {// 基础类型检查message: String,// 多种类型propA: [String, Number],// 必填项requiredProp: {type: String,required: true},// 带默认值propWithDefault: {type: Number,default: 100},// 对象/数组默认值objectProp: {type: Object,default: () => ({ key: 'value' })},// 自定义验证customProp: {validator(value) {return ['success', 'warning', 'danger'].includes(value)}}}
}

1.2 Emit 向上传递事件

子组件通过触发事件向父组件传递信息。

// 子组件
<template><div><button @click="sendToParent">发送到父组件</button></div>
</template><script>
export default {emits: ['update', 'delete'], // 声明组件发出的事件methods: {sendToParent() {// 触发事件并传递数据this.$emit('update', { id: 1, name: '更新的数据' })}}
}
</script>
// 父组件
<template><child-component @update="handleUpdate"@delete="handleDelete"/>
</template><script>
export default {methods: {handleUpdate(data) {console.log('收到子组件数据:', data)},handleDelete(id) {console.log('删除ID:', id)}}
}
</script>

2. EventBus 跨组件通信

2.1 创建事件总线

EventBus 允许任意组件间通信,不受组件层级限制。

// Vue 2 创建事件总线
// eventBus.js
import Vue from 'vue'
export const EventBus = new Vue()// Vue 3 创建事件总线
// eventBus.js
import mitt from 'mitt'
export const EventBus = mitt()

2.2 使用事件总线

// 组件A - 发送事件
import { EventBus } from '@/eventBus'export default {methods: {sendMessage() {// Vue 2EventBus.$emit('custom-event', { message: '这是一条消息' })// Vue 3EventBus.emit('custom-event', { message: '这是一条消息' })}}
}
// 组件B - 接收事件
import { EventBus } from '@/eventBus'export default {created() {// Vue 2EventBus.$on('custom-event', this.handleEvent)// Vue 3EventBus.on('custom-event', this.handleEvent)},beforeDestroy() { // Vue 2EventBus.$off('custom-event', this.handleEvent)},beforeUnmount() { // Vue 3EventBus.off('custom-event', this.handleEvent)},methods: {handleEvent(data) {console.log('收到事件数据:', data)}}
}

2.3 EventBus 优缺点

优点:

  • 使用简单,可实现任意组件间通信
  • 不需要组件间有直接的引用关系

缺点:

  • 可能导致事件混乱,难以追踪数据流向
  • 组件耦合度增加,不利于维护
  • 大型应用中建议使用Vuex/Pinia等状态管理方案

3. Provide/Inject 深层组件通信

3.1 基本使用

适用于深层嵌套组件间通信,祖先组件提供数据,后代组件注入使用。

// 祖先组件提供数据
export default {provide() {return {// 提供静态值theme: 'dark',// 提供响应式数据user: this.user,// 提供方法updateUser: this.updateUser}},data() {return {user: { name: '张三', role: 'admin' }}},methods: {updateUser(newUser) {this.user = newUser}}
}
// 后代组件注入数据
export default {inject: ['theme', 'user', 'updateUser'],// 或者使用别名和默认值inject: {appTheme: {from: 'theme',default: 'light'},currentUser: 'user'},methods: {changeUserRole() {this.updateUser({...this.currentUser, role: 'editor'})}}
}

3.2 响应式处理

Vue 3中使用provide/inject实现响应式通信:

// 祖先组件 (Vue 3)
import { provide, ref, readonly } from 'vue'export default {setup() {const count = ref(0)function increment() {count.value++}// 提供只读值防止子组件修改provide('count', readonly(count))provide('increment', increment)return { count, increment }}
}
// 后代组件 (Vue 3)
import { inject } from 'vue'export default {setup() {const count = inject('count')const increment = inject('increment')return { count, increment }}
}

3.3 Provide/Inject 优缺点

优点:

  • 解决深层嵌套组件通信问题
  • 避免了"prop drilling"(属性透传)
  • Vue 3中与组合式API结合使用更加灵活

缺点:

  • 增加了组件间的隐式依赖
  • 重构时可能导致问题
  • 数据来源不明确,可能影响代码可维护性

4. 各通信方式对比与选择

通信方式适用场景优点缺点
Props/Emit父子组件通信简单直接,Vue官方推荐层级深时需要多层传递
EventBus任意组件间通信使用简单,无需组件关系事件难以追踪,大型应用不推荐
Provide/Inject深层组件通信避免属性透传增加隐式依赖
Vuex/Pinia复杂应用状态管理集中管理状态,状态变化可追踪小型应用可能过于复杂
a t t r s / attrs/ attrs/listeners透传属性和事件无需显式声明即可传递仅适用于中间层组件传递

5. 最佳实践建议

  1. 就近原则:优先使用最简单的通信方式解决问题
  2. 明确数据流:保持单向数据流,便于追踪和调试
  3. 合理拆分组件:减少不必要的组件嵌套和通信
  4. 状态提升:将共享状态提升到最近的共同父组件
  5. 大型应用:考虑使用Vuex/Pinia进行状态管理
  6. 文档化:为组件间的通信方式编写清晰的文档

通过合理选择和组合这些通信方式,可以构建出数据流清晰、易于维护的Vue应用。

结语
感谢您的阅读!期待您的一键三连!欢迎指正!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vulnhub sunset系列靶机合集(部分)

描述&#xff1a;该合集包含sunset系列适合新手的四个靶机&#xff08;sunset:1、dusk、sunrise、noontide&#xff09;的渗透全过程。 靶机下载地址&#xff1a;Vulnerable By Design - Search: sunset ~ VulnHubhttps://www.vulnhub.com/?qsunset sunset:1 渗透过程 信息…

【MySQL】MySQL的基础语法及其语句的介绍

1、基础语法 mysql -h【主机名】 -u【用户名】 -p //登录MySQL exit或quit; //退出MySQL show database; //查看MySQL下的所有数据库 use 【数据库名】; //进入数据库 show tables; //查看数据库下的所有表名 *MySQL的启动和关闭 &am…

2025-4-20-C++ 学习 数组(1)

数组 2025-4-20-C++ 学习 数组(1)P1428 小鱼比可爱题目描述输入格式输出格式输入输出样例 #1输入 #1输出 #1说明/提示题解代码P1427 小鱼的数字游戏题目描述输入格式输出格式输入输出样例 #1输入 #1输出 #1说明/提示数据规模与约定题解代码P5727 【深基5.例3】冰雹猜想题目描…

ESP-ADF外设子系统深度解析:esp_peripherals组件架构与核心设计(显示输出类外设之LCD)

目录 ESP-ADF外设子系统深度解析&#xff1a;esp_peripherals组件架构与核心设计&#xff08;显示输出类外设之LCD&#xff09;简介模块概述功能定义架构位置核心特性 LCD外设分析LCD外设概述LCD外设层次架构图 LCD外设API和数据结构外设层API公共API内部数据结构 LCD外设配置选…

面试题:循环引用两个节点相互引用,如何判断哪个用 shared_ptr?哪个用 weak_ptr?

目录 1.引言 2.原理 3.所有权模型与指针选择 4.复杂场景的决策策略 5.注意事项 6.总结 1.引言 当两个对象通过 shared_ptr 相互引用时&#xff0c;会产生循环引用问题&#xff0c;导致内存泄漏。因为这两个对象的引用计数永远不会变为 0&#xff0c;即使它们在程序的其他…

QT聊天项目DAY06

1.从git上同步项目 编译测试&#xff0c;编译通过 Post请求测试 测试成功 2. email is 打印有问题&#xff0c;检查 解析结果是存储在jsonResult中的&#xff0c;修改 3. 客户端实现Post验证码请求 3.1 同步Qt客户端项目 检查QT版本&#xff0c;由于我在公司用的还是QT5.12.9…

PHP腾讯云人脸核身获取FaceId

参考腾讯云官方文档&#xff1a; 人脸核身 合作方后台上传身份信息_腾讯云 前提&#xff1a;已经获取了SIGN Ticket。获取参考文档&#xff1a; PHP腾讯云人脸核身获取SIGN Ticket-CSDN博客 public function getTxFaceId($uid,$name,$idNo){$appId ;$userId $uid;$nonce …

用 Deepseek 写的uniapp油耗计算器

下面是一个基于 Uniapp 的油耗计算器实现&#xff0c;包含 Vue 组件和页面代码。 1. 创建页面文件 在 pages 目录下创建 fuel-calculator 页面&#xff1a; <!-- pages/fuel-calculator/fuel-calculator.vue --> <template><view class"container"…

Redis ④-通用命令

Redis 是一个 客户端-服务器 结构的程序&#xff0c;这与 MySQL 是类似的&#xff0c;这点需要牢记&#xff01;&#xff01;&#xff01; Redis 固然好&#xff0c;但也不是任何场景都适合使用 Redis&#xff0c;一定要根据当前的业务需求来选择是否使用 Redis Redis 通用命令…

HarmonyOs学习 环境配置后 实验1:创建项目Hello World

HarmonyOS开发入门&#xff1a;环境配置与Hello World实验 实验目标 掌握HarmonyOS开发环境配置&#xff0c;创建首个HarmonyOS应用并实现"Hello World"界面展示 实验准备 已安装DevEco Studio开发环境已配置HarmonyOS开发依赖项熟悉基本TypeScript/ArkTS语法&am…

HTTP:十.cookie机制

Cookie概念及类型 HTTP cookie,简称cookie,又称数码存根、“网站/浏览+魔饼/魔片”等,是浏览网站时由网络服务器创建并由网页浏览器存放在用户计算机或其他设备的小文本文件。Cookie使Web服务器能在用户的设备存储状态信息(如添加到在线商店购物车中的商品)或跟踪用户…

记录小程序第一次调用Api,基于腾讯云Serverless函数,实现小程序的成功接入api,以及数据调用

目录 创建腾讯云个人账户新建severless应用建立函数URL小程序中调用api示例 创建腾讯云个人账户 百度搜索即可&#xff0c;并注册 新建severless应用 作者以github下载的某Api为例&#xff0c;这里不展示具体Api&#xff0c;只关注操作即可&#xff0c;相信都是互通的 在腾…

ES6 第一讲 变量定义 堆与栈 字符串的扩展和数值型的扩展

文章目录 1.ES6变量定义2.ES6堆和栈3.字符串的扩展3.1 模板字符串3.2 判断是否以指定的字符串开头或结尾3.3 字符串重复输出3.4 填充方法3.5 去除前后字符串空格3.6 返回参数指定位置的字符 4. 数值型的扩展4.1 二进制0B 八进制0O4.2 判断是否是一个无穷大的数字 &#xff08;判…

LeetCode第158题_用Read4读取N个字符 II

LeetCode 第158题&#xff1a;用Read4读取N个字符 II 题目描述 给你一个文件&#xff0c;并且该文件只能通过给定的 read4 方法来读取&#xff0c;请实现一个方法来读取 n 个字符。 read4 方法&#xff1a; API read4 可以从文件中读取 4 个连续的字符&#xff0c;并且将它…

算法篇之单调栈

单调栈算法入门 单调栈是一种特殊的数据结构应用&#xff0c;它的核心在于维护一个栈&#xff0c;使得栈内元素保持单调递增或者单调递减的顺序。这种数据结构在解决很多算法问题时非常有效&#xff0c;例如求数组中每个元素的下一个更大元素、每日温度问题等。 一、单调栈的…

Kubernetes控制平面组件:调度器Scheduler(二)

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

【网络】数据链路层知识梳理

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的笔记吧~ 自己写自己的八股&#xff01;让未来的自己看懂&#xff01; &#xff08;全文手敲&#xff0c;受益良多&#xff09; 数据链路层 我们来重新理解一下这个图&#xff1a;…

机器学习(神经网络基础篇)——个人理解篇6(概念+代码)

1 在声明一个类中&#xff0c;构建一个属于类的函数&#xff0c;前面为什要加上“self”&#xff1f; 就像下面这一串代码&#xff1a; class TwoLayerNet:def __init__(self, input_size, hidden_size, output_size,weight_init_std0.01):# 初始化权重self.params {}self.p…

Cribl 对Windows-xml log 进行 -Removing filed-06

Removing Fields Description​ The Eval Function can be used to add or remove fields. In this example we will remove the extracted fields while preserving _raw, _time,index,source, sourcetype. Steps - Adding an Eval Function

chili3d调试6 添加左侧面板

注释前 一个一个注释看对应哪个窗口 无事发生 子方法不是显示的窗口 注释掉看看 没了 注释这个看看 零件页面没了 这个浏览器居然完全不用关的&#xff0c;刷新就重载了 注释看看 无工具栏版本 sidebar&#xff1a; 往框框里面加入 div({ className: style.input }, user_…