Vue组件通信方式详解(全面版)

Vue应用开发中,组件通信是一个重要的话题。不同的组件可能需要在不同的情况下进行数据传递和交互。Vue提供了多种方式来实现组件通信,每种方式都有其适用的场景。本文将详细介绍Vue中实现组件通信的各种方式,并为每种方式提供通俗易懂的代码示例。

公众号:Code程序人生,个人网站:https://creatorblog.cn

Props

Props是父组件向子组件传递数据的一种方式。子组件通过在声明中指定props属性来接收父组件传递的数据。

<!-- ParentComponent.vue -->
<template><ChildComponent message="Hello from parent!" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent,},
};
</script><!-- ChildComponent.vue -->
<template><div>{{ message }}</div>
</template><script>
export default {props: ['message'],
};
</script>

自定义事件

子组件可以使用$emit触发一个自定义事件,父组件通过在子组件上使用v-on监听该事件并执行相应的方法。

<!-- ChildComponent.vue -->
<template><button @click="sendMessage">Send Message to Parent</button>
</template><script>
export default {methods: {sendMessage() {this.$emit('message-sent', 'Hello from child!');},},
};
</script><!-- ParentComponent.vue -->
<template><ChildComponent @message-sent="handleMessage" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent,},methods: {handleMessage(message) {console.log(message); // Output: "Hello from child!"},},
};
</script>

事件总线(Event Bus)

事件总线是一个空的Vue实例,可以用于在任何组件间发布和订阅事件。

<!-- EventBus.js -->
import Vue from 'vue';
export const eventBus = new Vue();<!-- FirstComponent.vue -->
<template><button @click="sendMessage">Send Message to SecondComponent</button>
</template><script>
import { eventBus } from './EventBus.js';export default {methods: {sendMessage() {eventBus.$emit('message-sent', 'Hello from first component!');},},
};
</script><!-- SecondComponent.vue -->
<template><div>{{ message }}</div>
</template><script>
import { eventBus } from './EventBus.js';export default {data() {return {message: '',};},created() {eventBus.$on('message-sent', (message) => {this.message = message;});},
};
</script>

Vuex

VuexVue的状态管理库,用于在不同组件间共享状态。

<!-- store/index.js -->
import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({state: {message: '',},mutations: {updateMessage(state, message) {state.message = message;},},
});<!-- FirstComponent.vue -->
<template><button @click="updateMessage">Update Message in SecondComponent</button>
</template><script>
import { mapMutations } from 'vuex';export default {methods: {...mapMutations(['updateMessage']),updateMessage() {this.updateMessage('Hello from first component!');},},
};
</script><!-- SecondComponent.vue -->
<template><div>{{ message }}</div>
</template><script>
import { mapState } from 'vuex';export default {computed: {...mapState(['message']),},
};
</script>

$parent 和 $children

Vue提供了$parent$children属性来访问父组件和子组件的实例。

<!-- ParentComponent.vue -->
<template><div><ChildComponent /></div>
</template><!-- ChildComponent.vue -->
<template><button @click="sendMessage">Send Message to Parent</button>
</template><script>
export default {methods: {sendMessage() {this.$parent.message = 'Hello from child!';},},
};
</script>

依赖注入

依赖注入是一种高级的通信方式,适用于祖先组件向后代组件传递数据,而不需要显式地通过props传递。

<!-- AncestorComponent.vue -->
<template><DescendantComponent />
</template><script>
import { provide } from 'vue';
import DescendantComponent from './DescendantComponent.vue';export default {components: {DescendantComponent,},setup() {provide('message', 'Hello from ancestor!');},
};
</script><!-- DescendantComponent.vue -->
<template><div>{{ message }}</div>
</template><script>
import { inject } from 'vue';export default {setup() {const message = inject('message');return {message,};},
};
</script>

$attrs 和 $listeners

$attrs$listeners 允许将父组件中非 prop 特性和事件传递给子组件,用于更灵活的组件封装。

<!-- ParentComponent.vue -->
<template><ChildComponent title="Hello" @custom-event="handleEvent" />
</template><!-- ChildComponent.vue -->
<template><div><h1>{{ title }}</h1><button @click="$emit('custom-event', 'Custom Event')">Click</button></div>
</template><script>
export default {props: ['title'],
};
</script>

插槽(Slots)

插槽允许父组件向子组件传递内容,而不仅仅是数据。

<!-- ParentComponent.vue -->
<template><ChildComponent><p>Slot content from parent</p></ChildComponent>
</template><!-- ChildComponent.vue -->
<template><div><slot></slot></div>
</template>

$refs

$refs 允许父组件访问子组件的实例,从而进行直接通信。

<!-- ParentComponent.vue -->
<template><div><ChildComponent ref="childRef" /><button @click="sendMessageToChild">Send Message to Child</button></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent,},methods: {sendMessageToChild() {this.$refs.childRef.receiveMessage('Hello from parent!');},},
};
</script><!-- ChildComponent.vue -->
<template><div>{{ message }}</div>
</template><script>
export default {data() {return {message: '',};},methods: {receiveMessage(message) {this.message = message;},},
};
</script>

localStorage或sessionStorage

浏览器缓存在一定程序上也可以帮助我们实现组件通信,甚至跨页面、跨窗口通信,但是在Vue项目中有很多更优秀的通信方式,不是很建议使用localStoragesessionStorage来实现。

// 在一个页面中存储数据
localStorage.setItem('message', 'Hello from localStorage');// 在另一个页面中获取数据
const message = localStorage.getItem('message');
console.log(message); // "Hello from localStorage"

总结

组件通信是我们日常开发中最常见的功能,可以这样说,有组件的地方就有组件通信的需求,而现在所有框架都朝着组件化、工程化的方向发展,所以组件通信是我们必须掌握的。

上述内容详细介绍了Vue中实现组件通信的多种方式,提供了基本的代码示例。它们有各自的使用场景,大家可以根据不同的场景和需求,选择合适的通信方式可以让你的Vue应用更加高效和可维护。

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

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

相关文章

stm32之4.时钟体系

3.时钟体系(给单片机提供一个非常稳定的频率信号) ①可以使用三种不同的时钟源来驱动系统时钟&#xff08;SYSCLK&#xff09;&#xff0c;CPU运行的频率为168MHZ&#xff1b; HSI(RC振荡器时钟&#xff0c;也就是高速内部时钟&#xff0c;一般来说很少用&#xff0c;因为精度…

【Image captioning】自用数据集预处理并提取Resnet特征

自用数据集预处理并提取Resnet特征 作者:安静到无声 个人主页 目录 自用数据集预处理并提取Resnet特征将uic_coco.json转换为uictalk.json和uictalk_label.h5Resnet特征提取推荐专栏注意本文的所使用的数据集是我自己创作的uic自有集。 将uic_coco.json转换为uictalk.json和…

二叉树的层序遍历及完全二叉树的判断

文章目录 1.二叉树层序遍历 2.完全二叉树的判断 文章内容 1.二叉树层序遍历 二叉树的层序遍历需要一个队列来帮助实现。 我们在队列中存储的是节点的地址&#xff0c;所以我们要对队列结构体的数据域重定义&#xff0c; 以上代码 从逻辑上来讲就是1入队&#xff0c;1出队&am…

字节跳动 从需求到上线全流程 软件工程流程 需求评估 MVP

走进后端开发流程 整个课程会带大家先从理论出发&#xff0c;思考为什么有流程 大家以后工作的团队可能不一样&#xff0c;那么不同的团队也会有不同的流程&#xff0c;这背后的逻辑是什么 然后会带大家按照走一遍从需求到上线的全流程&#xff0c;告诉大家在流程的每个阶段&am…

ROS JsonCPP 安装配置教程

以下是在ROS中安装配置JsonCPP的步骤&#xff1a; 在终端中输入以下命令来安装JsonCPP的依赖项&#xff1a; sudo apt-get install cmake sudo apt-get install libjsoncpp-dev创建一个新的ROS工作空间&#xff08;如果你已经有一个工作空间&#xff0c;请跳过此步骤&#xf…

视频集中存储/直播点播平台EasyDSS内核无法启动是什么原因?

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 有用户反馈&#xff0c;下载了视频直播点播平台EasyDSS最新版本&a…

桃子叶片病害识别(Python代码,pyTorch框架,深度卷积网络模型,很容易替换为其它模型,带有GUI识别界面)

1.分为三类 健康的桃子叶片 &#xff0c;251张 桃疮痂病一般&#xff0c;857张 桃疮痂病严重&#xff0c;770 张 2. GUI界面识别效果和predict.py识别效果如视频所示桃子叶片病害识别&#xff08;Python代码&#xff0c;pyTorch框架&#xff0c;深度卷积网络模型&#xff0…

嵌入性视角下的企业集成创新网络演化过程

从嵌入性角度来看&#xff0c;集成创新网络以社会关系嵌入或结构嵌入的联结方式&#xff0c;实 现创新资源共享。由于规模经济和能力的差异&#xff0c;较高的信息复杂程度往往更强调网 络化和外部组织之间的联合而不是一体化。企业集成创新网络依靠创新网络结点上 企业的合…

【数据结构】如何用栈实现队列?图文解析(LeetCode)

LeetCode链接&#xff1a;232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 注&#xff1a;本文默认读者已掌握栈与队列的基本操作 可以看这篇文章熟悉知识点&#xff1a;【数据结构】栈与队列_字节连结的博客-CSDN博客 目录 做题思路 代码实现 1. MyQueue 2. …

基于配置类方式管理 Bean

目录 一、完全注解开发理解 二、配置类和扫描注解 三、Bean定义组件 四、Bean注解细节 五、import 扩展 一、完全注解开发理解 Spring 完全注解配置&#xff08;Fully Annotation-based Configuration&#xff09;是指通过 Java配置类 代码来配置 Spring 应用程序&#…

ubuntu安装Google Chrome 浏览器和ChromeDriver

要在Ubuntu上安装Google Chrome浏览器和ChromeDriver&#xff0c;可以按照以下步骤操作&#xff1a; 1. 安装Google Chrome 浏览器 下载Google Chrome 的最新版本。 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb使用dpkg安装下载的deb包。…

根据订单项id获取订单项

目录 1 himall3.0商城源码 1.1 /// 根据订单项id获取订单项 1.2 /// 获取订单的评论数 1.3 /// 根据订单项id获取售后记录 himall3.0商城源码 public static List<InvoiceTitleInfo> GetInvoiceTitles(long userid) {

【OCR识别】tess4j图片识别文字

什么是OCR? OCR &#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;是指电子设备&#xff08;例如扫描仪或数码相机&#xff09;检查纸上打印的字符&#xff0c;通过检测暗、亮的模式确定其形状&#xff0c;然后用字符识别方法将形状翻译成计算机…

使用Docker进行模型部署

一、常见的模型部署场景 实时的、小数据量的预测应用 部署方式&#xff1a;采用python-httpserve应用部署&#xff08;如flask, fastApi, django&#xff09;&#xff0c;缺点是可能需要跨环境&#xff0c;从Java跨到Python环境实时的、大数据量的预测应用 部署方式&#xff1…

【力扣】349. 两个数组的交集 <哈希>

【力扣】349. 两个数组的交集 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 输出&#xff1a;[2] 示例 2&#…

MongoDB入门

简介 MongoDB是一个开源、高性能、支持海量数据存储的文档型数据库 是NoSQL数据库产品中的一种&#xff0c;是最像关系型数据库&#xff08;MySQL&#xff09;的非关系型数据库 内部采用BSON(二进制JSON)格式来存储数据,并支持水平扩展。 MongoDB本身并不是完全免费的,它对…

《C和指针》笔记10:作用域

结合上面的例子讲解C语言的作用域。 1. 代码块作用域 (block scope) 位于一对花括号之间的所有语句称为一个代码块。任何在代码块的开始位置声明的标识符都具有代码块作用域 (block scope)&#xff0c;表示它们可以被这个代码块中的所有语句访问。上图中标识为6、7、9、10的变…

Unity C# 之 Task、async和 await 结合使用的一些情况处理

Unity C# 之 Task、async和 await 结合使用的一些情况处理 目录 Unity C# 之 Task、async和 await 结合使用的一些情况处理 一、简单介绍 二、把 async 函数&#xff0c;通过变化转为一般的函数 三、在 async 函数中&#xff0c;切换到主线程&#xff0c;并等待主线程执行…

Ubuntu释放VMware虚拟磁盘未使用空间

By: Ailson Jack Date: 2023.08.26 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/152.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

echarts 甘特图一组显示多组数据

<template><el-button type"primary" click"addlin">添加线</el-button><el-button type"success" click"addArea">添加区域</el-button><div ref"echart" id"echart" class&qu…