Vue 组件通信指南:Props 和 $emit,Vuex(状态管理),EventBus(事件总线),Provide/Inject(依赖注入)

news2024/9/21 13:13:34

Snipaste_2023-10-14_13-39-18.png

引言

在 Vue 中,组件是构建应用的基本单元,而组件通信则是构建复杂应用的关键。组件通信是指在不同的 Vue 组件之间传递数据、交互和共享状态的过程,它在构建大型应用和组织代码方面起着至关重要的作用。

在开发过程中,我们经常会遇到父子组件的通信、兄弟组件之间的数据传递、跨级组件之间的通信等场景。为了解决这些问题,Vue 提供了多种方式来实现组件通信,如 Props$emit事件总线Vuex 状态管理等。每种方式都有其独特的优势和适用场景。

本篇文章将详细介绍 Vue 组件通信的各种方式,包括父子组件通信、兄弟组件通信、跨级组件通信和非父子组件通信。让我们深入研究 Vue 组件通信,提升我们在 Vue 应用开发中的技能和效率。

一. 父子组件通信

父组件向子组件传递数据

Props 属性传递

当我们需要在父组件中向子组件传递数据时,Vue 提供了一种非常方便的方式,那就是通过 Props 属性传递。下面进行具体的代码示例:

父组件:

<template>
  <div>
    <h1>父组件</h1>
    <ChildComponent :message="message" />
  </div>
</template>

<script>
import ChildComponent from "./ChildComponent.vue";

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      message: "Hello, Child!",
    };
  },
};
</script>

子组件:

<template>
  <div>
    <h2>子组件</h2>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true,
    },
  },
};
</script>

在父组件中,我们通过给子组件的属性绑定一对:,并将需要传递的数据绑定到属性上。在这个例子中,我们将message属性绑定到了子组件的message属性上。

在子组件中,我们使用props选项来声明接受父组件传递的属性。我们可以指定属性的类型和是否是必需的。在这个例子中,我们指定了message属性的类型为字符串,并设置为必需的(required)。

当父组件的数据发生变化时,子组件会自动更新渲染,并显示父组件传递过来的数据。

通过这种方式,我们可以轻松地将数据从父组件传递到子组件,实现组件间的数据传递和通信。同时,使用 Props 属性还可以保证父组件和子组件之间的数据流清晰明了,便于维护和追踪数据变化。

子组件向父组件传递数据

$emit 触发自定义事件

当子组件需要向父组件传递数据时,可以使用$emit方法触发自定义事件。通过自定义事件,子组件可以向父组件发送任意类型的数据。

父组件:

<template>
  <div>
    <h1>父组件</h1>
    <ChildComponent @childEvent="handleChildEvent" />
    <p>接收到子组件传递的数据:{{ childData }}</p>
  </div>
</template>

<script>
import ChildComponent from "./ChildComponent.vue";

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      childData: "",
    };
  },
  methods: {
    handleChildEvent(data) {
      this.childData = data;
    },
  },
};
</script>

子组件:

<template>
  <div>
    <h2>子组件</h2>
    <button @click="sendData">发送数据给父组件</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit("childEvent", "Hello, Parent!");
    },
  },
};
</script>

在这个例子中,子组件通过$emit方法触发了一个名为childEvent的自定义事件,并传递了一个字符串数据Hello, Parent!

在父组件中,我们在子组件的标签上使用了childEvent监听子组件触发的childEvent事件,并在ChildEvent方法中处理收到的数据,将其保存到childData变量中。

当我们点击子组件中的按钮时,sendData方法会被触发,通过$emit触发childEvent事件,父组件中的handleChildEvent方法会被调用,接收到子组件传递的数据并更新childData变量。

通过以上的这种方式,子组件可以方便地向父组件传递数据,实现组件间的双向通信。

Props和$emit是最常见的组件通信方式,也是应用最广泛的通信方式。

二. 兄弟组件通信

在 Vue 中,兄弟组件之间没有直接的通信方式。但我们可以通过共同的父组件来实现兄弟组件的通信。

使用共同的父组件作为中介

  • 通过共同的父组件来传递数据或触发事件,实现兄弟组件之间的通信。

  • 父组件作为中介,在接收到一个组件的数据或事件后,再将其传递给另一个组件。

这是一种简单的方式,通过共同的父组件作为中介,在父组件中存储需要共享的数据,并通过 props 将数据传递给需要通信的兄弟组件,当其中一个兄弟组件修改数据时,通过触发事件,将数据传递给父组件,然后由父组件将数据传递给其他兄弟组件。

父组件 Parent.vue

<!-- Parent.vue -->
<template>
  <div>
    <ChildA :message="message" @emitMessage="handleMessage" />
    <ChildB :message="message" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "",
    };
  },
  methods: {
    handleMessage(message) {
      this.message = message;
    },
  },
};
</script>

子组件 ChildA.vue

<!-- ChildA.vue -->
<template>
  <div>
    <input v-model="message" />
    <button @click="sendMessage">发送消息</button>
  </div>
</template>

<script>
export default {
  props: ["message"],
  methods: {
    sendMessage() {
      this.$emit("emitMessage", this.message);
    },
  },
};
</script>

子组件 ChildB.vue

<!-- ChildB.vue -->
<template>
  <div>
    <p>接收到的消息:{{ message }}</p>
  </div>
</template>

<script>
export default {
  props: ["message"],
};
</script>

在这个示例中,Parent.vue 作为两个兄弟组件 ChildA.vue 和 ChildB.vue 的共同父组件。ChildA.vue 通过 props 接收一个 message 属性,并在按钮点击事件时通过 emit 方法将 message 传递给 Parent.vue。Parent.vue 接收到 ChildA.vue 发送的消息后,通过 data 属性将 message 传递给 ChildB.vue,ChildB.vue 则通过 props 接收 message 并进行展示。

通过这种方式,兄弟组件之间可以进行通信,实现数据的共享和更新。

父子组件通信和兄弟组件通信都是常见的组件通信,其他的譬如“跨级组件”、“非父子组件”之间是如何通信的?是否还有其他的通信方式?

三. 选择最佳的通信方式

在实际开发中,有多种方式可以实现 Vue 组件通信,每种方式都有自己的特点和适用场景。以下是 Vue 组件通信的常见方式及其最佳实践总结:

1. Props 和 $emit

说明:

  • Props: 父组件通过属性传递数据给子组件,子组件通过 props 接收数据。适用于父子组件之间的通信。

  • $emit: 子组件通过触发自定义事件并传递数据给父组件,父组件通过 $emit 监听子组件的事件。适用于子组件向父组件传递数据和触发特定操作。

最佳实践:

在父子组件之间进行简单的数据传递、状态管理和发事件时,使用 Props 和$emit 是一种简单有效的方式。

2. Vuex(状态管理)

说明:

  • Vuex 是 Vue 官方提供的状态管理模式和库,它将全部组件的状态集中存储在一个全局的 Store 中,通过 Mutations、Actions 和 Getters 等进行状态的修改、操作和获取。

  • 适用于大型复杂应用中多个组件之间的共享状态管理和通信。

详细了解请查看:

Vuex 入门与实战:了解 Vue 状态管理的核心概念icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142381694

Vuex 进阶知识:如何优雅的进行 Vue 的状态管理icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142381737

最佳实践:

当应用中组件之间的状态共享较多,或需要进行异步操作和复杂的数据处理时,使用 Vuex 可以更好地管理和同步数据。

3. EventBus(事件总线)

说明:

  • EventBus 是一种基于发布/订阅模式的事件机制,它通过一个中央事件总线来进行多个组件之间的通信。通过发布事件和订阅事件来实现组件之间的信息传递。

  • 适用于多个组件之间的松散耦合的通信需求。

详细了解请查看:

组件通信的桥梁:探索 Vue 事件总线的原理与应用icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142351702

最佳实践:

当应用的组件之间关系较为复杂,需要松耦合的通信时,EventBus 是一种简洁方便的方式。但需注意在大型应用中,事件命名的规范和管理。

4. Provide/Inject(依赖注入)

说明:

  • Provide/Inject 是一种祖先组件向所有子孙后代组件进行数据传递的方式。通过在祖先组件中 provide 数据,然后在子组件中 inject 接收使用。

  • 适用于跨级组件之间进行数据传递,避免了多层级嵌套组件传递数据的繁琐。

详细了解请查看:

组件通信的“传送门”:深入剖析 Vue 中的依赖注入机制icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142351790

最佳实践:

在多层级嵌套的组件关系中需要进行数据传递时,Provide/Inject 是一种简洁高效的方式。但需注意数据的可追踪性和组件之间依赖的关系。

总结

选择合适的组件通信方式需要根据实际应用场景和需求来决定:

  1. 在简单的父子组件通信中,Props 和$emit 是最常见的方式;

  2. 在复杂的状态管理和异步操作中,使用 Vuex 可以更好地管理数据;

  3. 在多个组之间需要进行松散耦合的通信时,EventBus 是一种常用的方式;

  4. 在多层级嵌套组件中大范围进行数据传递时,Provide/Inject 可以简化传递过程。

根据具体情况选择最合适的组件通信方式,可以提高代码的可维护性和扩展性。

有兴趣的同学可以查阅我之前的有关组件通信的文章

组件通信的桥梁:探索 Vue 事件总线的原理与应用icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142351702

组件通信的“传送门”:深入剖析 Vue 中的依赖注入机制icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142351790

Vuex 入门与实战:了解 Vue 状态管理的核心概念icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142381694

Vuex 进阶知识:如何优雅的进行 Vue 的状态管理icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142381737

 

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

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

相关文章

一招教你挑代理IP的秘诀

逛乎&#xff0c;一直刷到这类问题&#xff1a; 本质上&#xff0c;都是在面对市面上那么多代理IP服务提供商&#xff0c;挑得眼花缭乱了&#xff0c;而代理IP直接影响到我们数据采集任务的效率、安全性和成功率&#xff0c;所以我们在挑选服务提供商的时候都会谨慎一些。索性我…

VScode安装和使用教程,2024最新最全,零基础入门到精通,看完这一篇就够了!

# VSCode 安装使用教程&#xff08;图文版&#xff09; 工欲善其事&#xff0c;必先利其器 对于我们每一位软件工程师来说&#xff0c;都要有自己顺手的 IDE 开发工具&#xff0c;它就是我们的武器。 一个好用的 IDE 不仅能提升我们的开发效率&#xff0c;还能让我们保持愉悦…

推送 Git Remote: 内部服务错误解决方案

Git Remote: 内部服务错误起因 拉取阿里云云效仓库代码的时候&#xff0c;之前一直拉取仓库并且推送都没有任何问题&#xff0c;但是最近在云效里面新建了一个仓库&#xff0c;也能成功拉取下来&#xff0c;但就是推送不上去&#xff0c;但是其它仓库都可以随意推送没有任何问…

IPv6(三)

文章目录 IPv6报文 IPv6报文 IPv6基本报头有8个字段&#xff0c;固定大小为40字节&#xff0c;&#xff0c;每个IPv6数据都必须包含报头&#xff0c;基本报头提供报文转发的基本信息&#xff0c;会被转发路径上面的所有路由器解析 IPv6报头长度为40字节Version&#xff1a;版本…

如何实现一个流畅的滚动列表

如何实现一个流畅的滚动列表 在网页开发中&#xff0c;滚动列表是展示大量数据时常用的交互方式。通过结合CSS动画和视觉设计&#xff0c;我们可以让列表内容自动滚动&#xff0c;为用户提供顺畅的浏览体验。今天&#xff0c;我将带你一步步实现一个流畅、富有视觉吸引力的滚动…

MySQL中的LIMIT与ORDER BY关键字详解

前言 众所周知&#xff0c;LIMIT和ORDER BY在数据库中&#xff0c;是两个非常关键并且经常一起使用的SQL语句部分&#xff0c;它们在数据处理和分页展示方面发挥着重要作用。 今天就结合工作中遇到的实际问题&#xff0c;回顾一下这块的知识点。同时希望这篇文章可以帮助到正…

[备忘]测算.net中对象所占用的内存

.net 基础库中应该是没有直接提供计算某个对象所占内存的方法。简单查了下&#xff0c;找到几种方式&#xff1a; 1、运行态用工具进行内存分析 比如&#xff0c;微软这篇教程中有介绍。《使用 .NET 对象分配工具分析内存使用情况》https://learn.microsoft.com/zh-cn/visuals…

Tomcat CVE-2017-12615漏洞复现

1.开启环境 cd /vulhub/tomcat/CVE-2017-12615 docker-compose up -d 一键启动环境 2.在首页进行抓包 修改为put方式提交 Tomcat允许适用put方法上传任意文件类型&#xff0c;但不允许jsp后缀文件上传&#xff0c;因此我们需要配合 windows的解析漏洞. 使用put /shell.jsp…

着色器ShaderMask

说明 实现一个渐变进度条&#xff0c;要求&#xff1a; 颜色渐变的过程是循序渐进的&#xff0c;而不是看起来像是将渐变条逐渐拉长了。 效果 源码 // 渐变进度条Stack(children: [// 背景色板Container(width: 300,height: 8,decoration: BoxDecoration(borderRadius: Bord…

【华为杯】2024华为杯数模研赛E题 解题思路

题目 高速公路应急车道紧急启用模型 问题背景 高速公路拥堵现象的原因众多&#xff0c;除了交通事故外&#xff0c;最典型的就是部分路段出现瓶颈现象&#xff0c;主要原因是车辆汇聚&#xff0c;而拥堵后又容易蔓延。高速公路一些特定的路段容易形成堵点&#xff0c;如匝道…

(done) 什么是 GMM? Gaussian Mixture Model,高斯混合模型

来源&#xff1a;https://www.bilibili.com/video/BV13b411w7Xj/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 &#xff08;视频质量很高&#xff0c;一共四个视频&#xff0c;我只看了一个&#xff09; 直接看视频吧&#xff0…

Qt (17)【Qt 文件操作 读写保存】

阅读导航 引言一、Qt文件概述二、输入输出设备类三、文件读写类四、文件和目录信息类五、自定义“记事本” 引言 在上一篇文章中&#xff0c;我们学习了Qt的事件处理机制&#xff0c;知道了如何响应用户的操作。但应用程序常常还需要处理文件&#xff0c;比如读写数据。所以&a…

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

整流电路的有源逆变工作状态

目录 1. 逆变的概念 2. 有源逆变的条件 3. 电流电路的概念 4. 产生逆变的条件 5. 三相桥式全控整流电路的有源逆变工作状态 6. 逆变角的概念 7. 逆变失败的原因 8. 最小逆变角的限制 整流电路的有源逆变状态是指通过控制整流器&#xff0c;使其将直流电源的能量反向送回…

yolo自动化项目实例解析(四)ui页面整理1 (1.85)

我们在上一章整理main.py 的if __name__ __main__: 内容还留下面这一段&#xff0c; from PyQt5.QtWidgets import *from lanrenauto.moni.moni import *from PyQt5.QtGui import *app QApplication(sys.argv) # 初始化Qt应用ratio screen_width / 2560 # 分辨率比例# 设…

python库tenacity最后一次重试忽略异常,并返回None

from tenacity import retry, stop_after_attemptretry(stopstop_after_attempt(3), retry_error_callbacklambda x:None) def my_function():print(retry...)print(1/0)result my_function() print(result)效果如下

【CPU】CPU的物理核、逻辑核、超线程判断及L1、L2、L3缓存、CacheLine和CPU的TBL说明

CPU物理核及L1、L2、L3及缓存 CPU缓存 CPU 缓存是一种用于存储临时数据以提高计算机程序性能的内存层次结构。它通常分为三个层次&#xff1a;L1&#xff08;一级&#xff09;、L2&#xff08;二级&#xff09;和L3&#xff08;三级&#xff09;缓存。缓存大小是CPU的重…

数据结构之算法复杂度

目录 前言 一、复杂度的概念 二、时间复杂度 三、大O的渐进表示法 四、空间复杂度 五、常见复杂度对比 总结 前言 本文主要讲述数据结构中的算法复杂度 一、复杂度的概念 算法在编写成可执行程序后&#xff0c;运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏…

【Node】如何关闭node被占用的端口

现象&#xff1a; 服务端口被占用Error: listen EADDRINUSE: address already in use :::10088 解决办法&#xff1a; 解决的思路就是把对应10088端口运行的程序给杀死。 1.去cmd输入 cd c:\Windows\System322.可以查看所有端口获取PID netstat -ano3.也可以用端口准确定位…

linux如何对c++进行内存分析

linux如何对c进行内存分析 背景分析方法以及原理原理分析结果以及重点关注 背景 在工作中&#xff0c;我遇到一个问题&#xff0c;需要将c写的进程部署到MCU上。由于MCU上可用的RAM 非常有限&#xff0c;所以在部署时就需要考虑到使用内存大小。所以为了搞清楚&#xff0c;内存…