当前位置: 首页 > news >正文

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.lryc.cn/news/140576.html

相关文章:

  • 什么是Promise对象?它的状态有哪些?如何使用Promise处理异步操作?以及 async、await
  • Android 之自定义绘制一
  • vue3 计算两个表单得到第三个表单数据
  • Premiere Pro软件安装包分享(附安装教程)
  • springboot设置文件上传大小,默认是1mb
  • Unity 之transform.LookAt() 调整一个物体的旋转,使其朝向指定的位置
  • linux————haproxy
  • 【80天学习完《深入理解计算机系统》】第十天 3.3 条件码寄存器【CF ZF SF OF】【set】
  • 使用WSL修改docker文件存储位置
  • 软件设计师学习笔记6-存储系统
  • 【TI毫米波雷达笔记】CCS雷达工程内存RAM指定(DATA_SECTION,以IWR6843AOP为例)
  • 安卓移动应用开发实训室建设方案
  • 我的编程学习过程
  • 亚马逊云科技 云技能孵化营 初识机器学习
  • 多种编程语言运行速度排名-10亿次除7求余数为0的数量
  • Web 应用框架 Express 构建 RESTful API
  • Orchestrator介绍一 简介安装与web端管理
  • 【C++心愿便利店】No.3---内联函数、auto、范围for、nullptr
  • CV:边缘检测的算法包含 Prewitt、Sobel、Laplacian 和 Canny。
  • 【算法系列篇】前缀和
  • 若依移动端Ruoyi-App 项目的后端项目入门
  • (学习笔记-调度算法)内存页面置换算法
  • 行为型模式-观察者模式
  • 前端面试:【新技术与趋势】WebAssembly、Serverless、GraphQL
  • 【ubuntu】 20.04 网络连接器图标不显示、有线未托管、设置界面中没有“网络”选项等问题解决方案
  • SpringCloud/SpringBoot多模块项目中配置公共AOP模块实现打印子模块Controller所有请求参数与日志
  • 【GeoDa实用技巧100例】022:geoda生成空间权重矩阵(邻接矩阵、距离矩阵)
  • 基于web的鲜花商城系统java jsp网上购物超市mysql源代码
  • 意外发现Cortex-M内核带的64bit时间戳,比32bit的DWT时钟周期计数器更方便,再也不用担心溢出问题了
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。