vue 组件之间相互传值的6种方法

Vue.js 中组件间通信的方法有很多种,以下是6种常见的直接或间接的组件传值方式:

1. Props(父向子)

  • 优点
    • 易于理解,符合单向数据流的原则,有利于代码维护。
  • 缺点
    • 数据只能从父组件传递到子组件,不能反向传递。如果需要多个层级传递,则需要逐层向下传递props。
    • 当应用规模扩大时,过度依赖props可能导致组件间耦合度提高。

2. 自定义事件(子向父)

  • 优点
    • 实现了数据从子组件向父组件的传递,遵循响应式设计原则。
  • 缺点
    • 只能实现相邻组件之间的通信,对于多层级嵌套组件间的通信较为复杂。
    • 如果组件间交互复杂,可能会导致大量自定义事件的使用,影响代码可读性和可维护性。

3. $refs 和直接调用方法

  • 优点
    • 在需要对子组件进行操作或获取其内部状态时非常方便。
  • 缺点
    • 违背了组件的封装原则,使父组件对子组件内部实现细节有过多了解和依赖。
    • 不适用于跨层级、非父子关系的组件间通信。

4. Vuex

  • 优点
    • 提供了一个中心化的状态管理机制,便于多个组件共享和管理状态。
    • 支持异步操作,适合大型项目,可以有效降低组件间的耦合度。
  • 缺点
    • 对小型项目来说,引入Vuex可能过于复杂,增加了项目的开发和学习成本。
    • 需要编写额外的store模块和actions/mutations/getters,增加了一定的代码量。

5. Event Bus(全局事件总线)

  • 优点
    • 简化任意组件间的通信,尤其适合不具有直接关联关系的组件之间进行消息传递。
  • 缺点
    • 全局事件容易造成命名冲突,需要谨慎管理事件名称。
    • 当项目较大时,难以追踪事件的来源和去向,维护起来较困难。
    • 随着项目复杂度提升,过度依赖Event Bus会导致整体架构混乱,不易于调试和维护。

6. provide/inject

  • 优点
    • 可以方便地在祖先组件中提供数据给任意后代组件,无需逐层传递props。
  • 缺点
    • 注入的数据不具备响应性(除非注入的是计算属性或者Vue实例的方法)。
    • 容易造成组件间隐式的强耦合,不利于组件独立性和可复用性。

详细代码示例

1. Props(父向子)

父组件向子组件传递数据

  • 父组件代码:
<template><ChildComponent :parentValue="valueFromParent" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {data() {return {valueFromParent: '这是父组件的数据'};},components: {ChildComponent}
};
</script>
  • 子组件代码:
<template><div>{{ parentValue }}</div>
</template><script>
export default {props: {parentValue: String // 接收并展示来自父组件的值}
};
</script>

2. 自定义事件(子向父)

子组件向父组件传递数据

  • 子组件代码:
<template><button @click="emitValue">点击传递数据</button>
</template><script>
export default {methods: {emitValue() {this.$emit('childEvent', '这是子组件传递的数据');}}
};
</script>
  • 父组件代码:
<template><ChildComponent @childEvent="handleChildEmit" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {methods: {handleChildEmit(value) {console.log('接收到子组件的数据:', value);// 更新父组件状态等操作}},components: {ChildComponent}
};
</script>

3. $refs 和直接调用方法

在某些情况下,可以通过 ref 获取到子组件实例并在父组件中直接调用其方法。

  • 子组件代码:
<template><div ref="childRef">...</div><button @click="sendData">发送数据</button>
</template><script>
export default {methods: {sendData() {this.$emit('dataSent', this.someData);}}
};
</script>
  • 父组件代码:
<template><ChildComponent ref="child" @dataSent="handleData" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {methods: {handleData(data) {console.log('通过事件接收的数据:', data);},callChildMethod() {// 使用 $refs 访问子组件实例并调用方法this.$refs.child.sendData();}},components: {ChildComponent}
};
</script>

4. Vuex

使用全局状态管理工具 Vuex 来实现跨多个层级组件间的通信。

  • 在 Vuex 中创建 store:
// store.js
import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({state: {sharedData: null},mutations: {setSharedData(state, data) {state.sharedData = data;}},actions: {updateSharedData({ commit }, newData) {commit('setSharedData', newData);}},getters: {getSharedData(state) {return state.sharedData;}}
});
  • 组件内使用:
// 任何组件内
<template><button @click="updateData">更新共享数据</button><AnotherComponent />
</template><script>
import { mapActions, mapGetters } from 'vuex';export default {computed: {...mapGetters(['getSharedData'])},methods: {...mapActions(['updateSharedData']),updateData() {this.updateSharedData({ some: 'new data' });}}
};
</script>

5. Event Bus(全局事件总线)

创建一个全局事件总线来允许任意组件之间进行通信。

// eventBus.js
import Vue from 'vue';export const EventBus = new Vue();
  • 发送事件的组件:
<template><button @click="sendMessage">发送消息</button>
</template><script>
import { EventBus } from './eventBus';export default {methods: {sendMessage() {EventBus.$emit('customEvent', { message: 'Hello from component A!' });}}
};
</script>
  • 接收事件的组件:
<script>
import { EventBus } from './eventBus';export default {created() {EventBus.$on('customEvent', (data) => {console.log('Received message:', data.message);});},beforeDestroy() {// 不要忘记在组件销毁时解绑事件监听器以避免内存泄漏EventBus.$off('customEvent');}
};
</script>

6. provide/inject

Vue 提供了 provideinject API 来实现祖先组件向后代组件提供依赖的方式(无需中间传递)。

  • 祖先组件提供数据:
<script>
export default {provide() {return {ancestorData: this.someData};},data() {return {someData: '来自祖先的数据'};}
};
</script>
  • 后代组件注入数据:
<script>
export default {inject: ['ancestorData'],mounted() {console.log('从祖先获取的数据:', this.ancestorData);}
};
</script>

以上每种方法都有其适用场景和优缺点,请根据实际项目需求选择合适的方式。

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

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

相关文章

AcWing 895. 最长上升子序列(DP序列模型)

[题目概述] 给定一个长度为 N 的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数 N。 第二行包含 N 个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 1 ≤ N ≤ 1000 &#xff0c; …

【刷题】 leetcode 面试题 08.05.递归乘法

递归乘法 1 题目描述2 思路一&#xff08;返璞归真版&#xff09;3 思路二&#xff08;二进制乘法器版&#xff09;4 思路三&#xff08;变态版&#xff09;Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下一篇文章见&#xff01;&#xff01;&#xff01; 1 题目…

go标准库Context上下文

为什么需要Context 基本示例 package mainimport ("fmt""sync""time" )var wg sync.WaitGroup// 初始的例子func worker() {for {fmt.Println("worker")time.Sleep(time.Second)}// 如何接收外部命令实现退出wg.Done() }func main()…

不确定优化入门:用简单实例讲明白随机规划、鲁棒优化和分布鲁棒优化

文章目录 1 引言2 学习动机3 经典问题4 解决方案4.1 忽略不确定性4.2 随机规划4.3 鲁棒优化4.4 分布鲁棒优化 5 总结相关阅读 1 引言 按2024的原定计划&#xff0c;今年开始要学习不确定优化了。 粗略翻阅了一些相关的书籍和教程&#xff0c;大都包含许多数学公式&#xff0c…

SpringBoot引入主盘探活定时任务

主盘探活通常是指检查存储设备&#xff08;例如硬盘&#xff09;是否可读写&#xff0c;但在Java中并没有直接针对硬件级别的磁盘探活API。然而&#xff0c;我们可以模拟一个场景&#xff0c;即检查某个目录或文件是否可以被Java程序正常读写&#xff0c;以此作为主盘活跃的一个…

HCIP复习课(bgp实验)

1、ip配置&#xff1a; R1&#xff1a; R2&#xff1a; R9&#xff1a; R10&#xff1a; R11&#xff1a; R3&#xff1a; R4&#xff1a; R5&#xff1a; R6&#xff1a; R7&#xff1a; R8&#xff1a; 2、隧道配置&#xff1a; R2&#xff1a; 静态&#xff1a; R10&am…

第15次修改了可删除可持久保存的前端html备忘录:换了一个容器时钟,匹配背景主题:现代深色

第15次修改了可删除可持久保存的前端html备忘录&#xff1a;换了一个容器时钟&#xff0c;匹配背景主题&#xff1a;现代深色 备忘录代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv&qu…

Python自动化框架命名约定(函数、模块、包、类等)

命名约定&#xff1a; 1. 所谓"内部(Internal)"表示仅模块内可用&#xff0c;或者&#xff0c;在类内是保护或私有的; 2. 用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含); 3. 用双下划线(__)开头的实例变量或方法表示类内…

WSL2 Debian系统添加支持SocketCAN

本人最近在使用WSL2&#xff0c;Linux系统选择的是Debian&#xff0c;用起来很不错&#xff0c;感觉可以代替VMware Player虚拟机。 但是WSL2 Debian默认不支持SocketCAN&#xff0c;这就有点坑了&#xff0c;由于本人经常要使用SocketCAN功能&#xff0c;所以决定让Debian支持…

Axolotl:一款极简的大模型微调(Finetune)开源框架

今天给大家分享一款工具&#xff0c;Axolotl[1] 是一个旨在简化各种AI模型的微调过程的工具&#xff0c;支持多种配置和架构。 特点&#xff1a; 可训练各种 Huggingface 模型&#xff0c;如 llama、pythia、falcon、mpt支持 fullfinetune、lora、qlora、relora 和 gptq使用简…

Maven入门及其使用

目录 一、Maven入门 1.1 初识Maven 1.2 Maven的作用 1.2.1 依赖管理 1.2.2 统一项目结构 1.2.3 项目构建 1.3 Maven坐标 1.4 Maven仓库 1.4.1 Maven仓库概述 二、Maven的下载与安装 2.1 安装步骤 2.1.1 解压安装&#xff08;建议解压到没有中文、特殊字符的路径下。&#xff09…

数据湖技术之应用场景篇

数据湖技术有较多的应用场景&#xff0c;本篇文章是针对一些典型的痛点场景做了一些介绍和说明。比如说在线数据抽取场景原有模式对线上库表产生较大压力&#xff0c;flink多流join维护的大状态导致的稳定性问题等等&#xff0c;具体场景如下图所示&#xff1a; 场景1:在线数据…

【极数系列】Flink详细入门教程 知识体系 学习路线(01)

文章目录 01 引言02 Flink是什么2.1 Flink简介2.2 Flink架构2.3 Flink应用场景2.4 Flink运维 03 Flink环境搭建3.1 Flink服务端环境搭建3.2 Flink部署模式3.3 Flink开发环境搭建 04 Flink数据类型以及序列化4.1 数据类型4.2 数据序列化 05 Flink DataStream API5.1 执行模式5.2…

车载电子电器架构 —— 多核处理器刷写策略

车载电子电器架构 —— 多核处理器刷写策略 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…

嵌入式Linux系统引导过程详解

大家好&#xff0c;今天给大家介绍嵌入式Linux系统引导过程详解&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 嵌入式Linux系统引导过程是系统启动的关键环节&#xff0c;它涉及…

代码随想录刷题笔记-Day10

1. 用栈实现队列 232.用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/description/ 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xf…

ID Mapping技术解析:从Redis到Spark GraphX的演进与应用

目录 一、ID Mapping的背景 二、ID Mapping的重要性 三、ID Mapping的方案 3.1 基于Redis的ID Mapping(效率不行)

Java基础数据结构之反射

一.定义 Java的反射机制是在运行状态中的&#xff0c;对于任意一个类都能知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法及属性。既然能拿到&#xff0c;我们就可以修改部分类型信息。这种动态获取信息以及动态调用对象方法的功能…

Django笔记(七):JWT认证

首 前后端分离的项目更多使用JWT认证——Json Web Token。本文记录djangorestframework-simplejwt的使用方式。文档 安装 pip install djangorestframework-simplejwt 配置settings.py: INSTALLED_APPS [rest_framework_simplejwt, ]REST_FRAMEWORK {DEFAULT_AUTHENTICA…

第一讲_JavaScript概述及三种使用方式

JavaScript概述及三种使用方式 1. JavaScript概述1.1 JavaScript 的作用 2 JavaScript使用方式2.1 行内使用2.2 内部使用2.3 外部使用 1. JavaScript概述 JavaScript主页由三部分组成&#xff1a; ECMAScript&#xff1a;规定 JavaScript 核心&#xff0c;定义了语言的基本语…