【干货】Vue3 组件通信方式详解

前言

毫无疑问,组件通信是Vue中非常重要的技术之一,它的出现能够使我们非常方便的在不同组件之间进行数据的传递,以达到数据交互的效果。所以,学习组件通信技术是非常有必要的,本文将总结Vue中关于组件通信的八种方式,帮助大家在使用Vue的过程中更加得心应手!

如果文中有不对、疑惑的地方,欢迎在评论区留言指正!!

一、什么是组件通信

在开始之前我们需要明白什么是组件通信,组件通信可以拆分为两个部分:

  • 组件
  • 通信

都知道组件是vue最强大的功能之一,vue中每一个.vue文件我们都可以视之为一个组件,简单来说组件就是对UI结构的复用。

通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的。广义上,任何信息的交通都是通信。而组件间通信即指组件(.vue)通过某种方式来传递信息以达到某个目的,举个栗子我们在使用UI框架中的table组件,可能会往table组件中传入某些数据,这个本质就形成了组件之间的通信

二、为什么要进行组件通信

通信的本质是信息同步,共享。回到vue中,每个组件之间的都有独自的作用域,组件间的数据是无法共享的但实际开发工作中我们常常需要让组件之间共享数据,这也是组件通信的目的要让它们互相之间能进行通讯,这样才能实现数据间的交互,完成某种功能的开发。

三、组件通信的分类

组件间通信的分类可以分成以下

  • 父子组件之间的通信
  • 兄弟组件之间的通信
  • 祖孙与后代组件之间的通信
  • 非关系组件间之间的通信

他们之间的关系如下图:

组件

目前最常用是props/$emitvuex/pinia ,接下来是 provide/inject,其他不建议使用;
实际项目中,简单父子组件传递采用props/$emit ,涉及全局共享的数据一般采用 vuex/pinia 结合存储对象localStorage/sessionStorage使用。

Vue3 组件通信方式

四、Vue3 的八种组件通信方式

  • props
  • $emit
  • expose / ref
  • $attrs
  • v-model
  • provide / inject
  • Vuex
  • mitt

五、Vue3 八种通信方式用法讲解

1. props

用 props 传数据给子组件有两种方法,如下

方法一,setup() 方法写法

// Parent.vue 传送
<child :msg1="msg1" :msg2="msg2"></child>
<script>
import child from "./child.vue"
import { ref, reactive } from "vue"
export default {data(){return {msg1:"这是传级子组件的信息1"}},setup(){// 创建一个响应式数据// 写法一 适用于基础类型  ref 还有其他用处,下面章节有介绍const msg2 = ref("这是传级子组件的信息2")// 写法二 适用于复杂类型,如数组、对象const msg2 = reactive(["这是传级子组件的信息2"])return {msg2}}
}
</script>// Child.vue 接收
<script>
export default {props: ["msg1", "msg2"],// 如果这行不写,下面就接收不到setup(props) {console.log(props) // { msg1:"这是传给子组件的信息1", msg2:"这是传给子组件的信息2" }},
}
</script>

方法二,setup 语法糖

// Parent.vue 传送
<child :msg2="msg2"></child>
<script setup>import child from "./child.vue"import { ref, reactive } from "vue"const msg2 = ref("这是传给子组件的信息2")// 或者复杂类型const msg2 = reactive(["这是传级子组件的信息2"])
</script>// Child.vue 接收
<script setup>// 不需要引入 直接使用// import { defineProps } from "vue"const props = defineProps({// 写法一msg2: String// 写法二msg2:{type:String,default:""}})console.log(props) // { msg2:"这是传级子组件的信息2" }
</script>

注意:

如果父组件是setup(),子组件setup 语法糖写法的话,是接收不到父组件里 data 的属性,只能接收到父组件里 setup 函数里传的属性。

如果父组件是setup 语法糖写法,子组件setup()方法写法,可以通过 props 接收到 data 和 setup 函数里的属性,但是子组件要是在 setup 里接收,同样只能接收到父组件中 setup 函数里的属性,接收不到 data 里的属性

官方也说了,既然用了 3,就不要写 2 了,所以不推荐setup()方法写法。下面的例子,一律只用语法糖的写法。

2. $emit

// Child.vue 派发
<template>// 写法一<button @click="emit('myClick')">按钮</buttom>// 写法二<button @click="handleClick">按钮</buttom>
</template>
<script setup>// 方法一 适用于Vue3.2版本 不需要引入// import { defineEmits } from "vue"// 对应写法一const emit = defineEmits(["myClick","myClick2"])// 对应写法二const handleClick = ()=>{emit("myClick", "这是发送给父组件的信息")}// 方法二 不适用于 Vue3.2版本,该版本 useContext()已废弃import { useContext } from "vue"const { emit } = useContext()const handleClick = ()=>{emit("myClick", "这是发送给父组件的信息")}
</script>// Parent.vue 响应
<template><child @myClick="onMyClick"></child>
</template>
<script setup>import child from "./child.vue"const onMyClick = (msg) => {console.log(msg) // 这是父组件收到的信息}
</script>

3. expose / ref

父组件获取子组件的属性或者调用子组件方法。

// Child.vue
<script setup>// 方法一 不适用于Vue3.2版本,该版本 useContext()已废弃import { useContext } from "vue"const ctx = useContext()// 对外暴露属性方法等都可以ctx.expose({childName: "这是子组件的属性",someMethod(){console.log("这是子组件的方法")}})// 方法二 适用于Vue3.2版本, 不需要引入// import { defineExpose } from "vue"defineExpose({childName: "这是子组件的属性",someMethod(){console.log("这是子组件的方法")}})
</script>// Parent.vue  注意 ref="comp"
<template><child ref="comp"></child><button @click="handlerClick">按钮</button>
</template>
<script setup>import child from "./child.vue"import { ref } from "vue"const comp = ref(null)const handlerClick = () => {console.log(comp.value.childName) // 获取子组件对外暴露的属性comp.value.someMethod() // 调用子组件对外暴露的方法}
</script>

4. attrs

attrs:包含父作用域里除 class 和 style 除外的非 props 属性集合

// Parent.vue 传送
<child :msg1="msg1" :msg2="msg2" title="3333"></child>
<script setup>import child from "./child.vue"import { ref, reactive } from "vue"const msg1 = ref("1111")const msg2 = ref("2222")
</script>// Child.vue 接收
<script setup>import { defineProps, useContext, useAttrs } from "vue"// 3.2版本不需要引入 defineProps,直接用const props = defineProps({msg1: String})// 方法一 不适用于 Vue3.2版本,该版本 useContext()已废弃const ctx = useContext()// 如果没有用 props 接收 msg1 的话就是 { msg1: "1111", msg2:"2222", title: "3333" }console.log(ctx.attrs) // { msg2:"2222", title: "3333" }// 方法二 适用于 Vue3.2版本const attrs = useAttrs()console.log(attrs) // { msg2:"2222", title: "3333" }
</script>

5. v-model

可以支持多个数据双向绑定

// Parent.vue
<child v-model:key="key" v-model:value="value"></child>
<script setup>import child from "./child.vue"import { ref, reactive } from "vue"const key = ref("1111")const value = ref("2222")
</script>// Child.vue
<template><button @click="handlerClick">按钮</button>
</template>
<script setup>// 方法一  不适用于 Vue3.2版本,该版本 useContext()已废弃import { useContext } from "vue"const { emit } = useContext()// 方法二 适用于 Vue3.2版本,不需要引入// import { defineEmits } from "vue"const emit = defineEmits(["key","value"])// 用法const handlerClick = () => {emit("update:key", "新的key")emit("update:value", "新的value")}
</script>

6. provide / inject

provide / inject 为依赖注入

provide:可以让我们指定想要提供给后代组件的数据或

inject:在任何后代组件中接收想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来用

// Parent.vue
<script setup>import { provide } from "vue"provide("name", "RDIF")
</script>// Child.vue
<script setup>import { inject } from "vue"const name = inject("name")console.log(name) // RDIF
</script>

7. Vuex

// store/index.js
import { createStore } from "vuex"
export default createStore({state:{ count: 1 },getters:{getCount: state => state.count},mutations:{add(state){state.count++}}
})// main.js
import { createApp } from "vue"
import App from "./App.vue"
import store from "./store"
createApp(App).use(store).mount("#app")// Page.vue
// 方法一 直接使用
<template><div>{{ $store.state.count }}</div><button @click="$store.commit('add')">按钮</button>
</template>// 方法二 获取
<script setup>import { useStore, computed } from "vuex"const store = useStore()console.log(store.state.count) // 1const count = computed(()=>store.state.count) // 响应式,会随着vuex数据改变而改变console.log(count) // 1 
</script>

8. mitt

Vue3 中没有了 EventBus 跨组件通信,但是现在有了一个替代的方案 mitt.js,原理还是 EventBus。

先安装 npm i mitt -S

然后像以前封装 bus 一样,封装一下

mitt.js
import mitt from 'mitt'
const mitt = mitt()
export default mitt

然后两个组件之间通信的使用

// 组件 A
<script setup>
import mitt from './mitt'
const handleClick = () => {mitt.emit('handleChange')
}
</script>// 组件 B 
<script setup>
import mitt from './mitt'
import { onUnmounted } from 'vue'
const someMethed = () => { ... }
mitt.on('handleChange',someMethed)
onUnmounted(()=>{mitt.off('handleChange',someMethed)
})
</script>

六、参考资料

vue.js: https://cn.vuejs.org/

vuex是什么:https://vuex.vuejs.org/zh/

工作中要使用Git,看这篇文章就够了:http://www.guosisoft.com/article/detail/410508049313861

企业数字化转型如何做?看过来:http://www.guosisoft.com/article/detail/408745545576517

【保姆级教程】Vue项目调试技巧:http://www.guosisoft.com/article/detail/430312211521605

Vue2.x 组件通信方式:http://www.guosisoft.com/article/detail/411234710110277

Vue 前端开发团队风格指南(史上最全):http://www.guosisoft.com/article/detail/415491255230533

国思RDIF低代码快速开发平台(支持vue2、vue3):http://www.guosisoft.com/article/detail/557095625134149

七、结语

如果本文对你有一点点帮助,点个赞支持一下吧,你的每一个【赞】都是我创作的最大动力 _

更多技术文章请往:http://www.guosisoft.com/article,大家一起共同交流和进步呀


一路走来数个年头,感谢RDIF框架的支持者与使用者,大家可以通过下面的地址了解详情。

官方网站:http://www.guosisoft.com/ http://www.rdiframework.net/

特别说明,框架相关的技术文章请以官方网站为准,欢迎大家收藏!

国思RDIF低代码快速开发框架由海南国思软件科技有限公司专业团队长期打造、一直在更新、一直在升级,请放心使用!

欢迎关注国思RDI低代码快速开发框架官方公众微信(微信号:guosisoft),及时了解最新动态。

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

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

相关文章

ArcGIS定义1.5度带坐标系与投影转换

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 对于ArcGIS如何定义高斯克吕格3度带、6度带&#xff0c;我相信大部分人都是比较清楚的&#xff0…

OAuth 2.0资源授权机制与安全风险分析

文章目录 前言OAuth2.01.1 OAuth应用1.2 OAuth基础1.3 授权码模式1.4 其它类模式1.5 openid连接 安全风险2.1 隐式授权劫持2.2 CSRF攻击风险2.3 Url重定向漏洞2.4 scope校验缺陷 总结 前言 OAuth 全称为Open Authorization&#xff08;开放授权&#xff09;&#xff0c;OAuth …

使用API有效率地管理Dynadot域名,为文件夹中的域名进行域名停放

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

“RLC串联正弦稳态电路的仿真研究”课程设计,高分资源,匠心制作,下载可用。强烈推荐!!!

1.设计目的 用 Multisim 电路仿真软件&#xff0c;对一个 RLC 串联电路进行正弦稳态电路分析。 2任务分析 2.1任务要求1 在 Multisim 中搭建一个 RLC 串联电路&#xff0c;其中 R、 L、 C、正弦激励源的振幅Vp和频率 f 等所有参数均可自己任意设置&#xff08;不建议都采用…

RT-Thread Studio实现静态线程

1创建项目 &#xff08;STM32F03ZET6&#xff09; RT-Thread项目与RT-Thread Nano 项目区别 RT-Thread: 完整版&#xff1a;这是RT-Thread的完整形态&#xff0c;适用于资源较丰富的物联网设备。功能&#xff1a;它提供了全面的中间件组件&#xff0c;如文件系统、网络协议栈、…

行业案例 | 智能终端设备的数据基础从哪儿来?

智能终端的快速发展让我们在许多科幻电影中看到的“未来场景”正在一步步变为现实&#xff1a;智能家居正在解放我们的双手&#xff0c;工业机器人让生产效率倍增&#xff0c;智能穿戴设备让我们便利地感知自身与外部的连结……然而&#xff0c;要想让万物“智联”&#xff0c;…

从环型到树型:多种网络拓扑结构的优缺点及应用

网络拓扑作为网络设计的基础&#xff0c;对于网络的性能、可靠性和扩展性起着重要作用。作为网络通信工程师&#xff0c;我们不仅需要了解网络拓扑的基本概念&#xff0c;还需深入掌握其在实际网络设计中的应用。本文将详细介绍网络拓扑&#xff0c;包括物理拓扑、逻辑拓扑&…

足底筋膜炎最快治疗方法有哪些

足底筋膜炎的治疗方式多样&#xff0c;因病而异&#xff0c;因人而异。为了快速有效地治疗足底筋膜炎&#xff0c;以下是一些建议的治疗方案&#xff1a; 1、物理治疗&#xff1a; 针灸、按摩、理疗、热敷等方式可以缓解局部炎症。这些物理治疗方法有助于促进血液循环&#xff…

windows下以服务方式安装prometheus和grafana

grafana 找到confi下的defaults.ini&#xff0c;找到http_port修改端口号 # The HTTP port to use http_port 3000启动 grafana-server.exe访问localhost:8601即可 下载winsw https://github.com/winsw/winsw 新建grafanaservice.xml <service><id>grafana&…

Strava VS Keep竞品分析

Strava VS Keep竞品分析 一、背景&#xff1a; 随着国民对身体健康的重视程度逐步增加&#xff0c;跑步、游泳、骑行在国内逐渐流行&#xff0c;人们都加入运动行列。随之不可缺少的则是对运动数据的记录&#xff0c;市面上针对此需求的app层出不穷&#xff0c;日活最多的5款…

用友BIP电子凭证3.0,助力企业实现结算自动化

电子凭证作为现代企业运营的核心数字凭据&#xff0c;其重要性不言而喻。它不仅是企业在社会经济活动中运动轨迹的记录&#xff0c;更是企业业务、财务、税务等关键数据信息的载体。特别是在企业与上下游企业之间的业务往来中&#xff0c;电子凭证所承载的订单数据、物流数据、…

智慧金融新视野:银行数据中心可视化大屏的崛起

在数字化浪潮的推动下&#xff0c;银行业正迎来一场前所未有的变革。在这场变革中&#xff0c;银行数据中心可视化大屏以其独特的魅力&#xff0c;为银行的数据分析和决策提供强有力的支持。 随着金融科技的不断发展&#xff0c;银行对于数据处理和分析的需求日益增长。银行数据…

写一个坏越的个人天地(四)

静态界面已经基本都写差不多了&#xff0c;今天试下部署看下问题然后就可以准备后端部分了~ 这边浏览了下先准备换下路径&#xff0c;确保本地素材的导入没有问题&#xff0c;vue打包这边有一个问题就是在打包的时候你的素材没有在标签里直接用src导入&#xff0c;而是在挂载的…

红酒舞动,运动风采,品味力与美

当夜幕降临&#xff0c;城市的灯火渐次亮起&#xff0c;忙碌了一天的人们开始寻找那份属于自己的宁静与愉悦。在这个时刻&#xff0c;红酒与运动&#xff0c;这两个看似截然不同的元素&#xff0c;却能以它们不同的魅力&#xff0c;为我们带来一场视觉与感官的盛宴。 红酒&…

如何学习训练大模型——100条建议(附详细说明)

摘要&#xff1a; 通过深入了解本文中的这些细节&#xff0c;并在实际项目中应用相关知识&#xff0c;将能够更好地理解和利用大模型的潜力&#xff0c;不仅在学术研究中&#xff0c;也在工程实践中。通过不断探索新方法、参与项目和保持热情&#xff0c;并将其应用于各种领域&…

探究电子电路中的电压与电平转换

1. 引言 昨天跟好朋友讨论一个项目的时候,我朋友就给我画了一个简化版的电路图&#xff0c;如下图所示&#xff1a; 总觉得这个电路怪怪的&#xff0c;clk信号怎么直接接稳压电路呢。就产生了一个疑问&#xff0c;电平转换和电压转换的区别是啥&#xff1f;稳压电路还有升降压…

【小白学Python】AI生成图片(四)

【小白学Python】自定义图片的生成&#xff08;一&#xff09; 【小白学Python】自定义图片的生成&#xff08;二&#xff09; 【小白学Python】爬取数据&#xff08;三&#xff09; 目录 ai文生图接口的获取python中调用ai接口图片拼接先将图片缩放拼接图片 文字背景图代码效…

【数据结构】(C语言):栈

栈&#xff1a; 线性的集合。后进先出&#xff08;LIFO&#xff0c;last in first out&#xff09;。两个指针&#xff1a;指向栈顶和栈底。栈顶指向最后进入且第一个出去的元素。栈底指向第一个进入且最后一个出去的元素。两个操作&#xff1a;入栈&#xff08;往栈尾添加元素…

Redis服务

目录 1、介绍 1、redis的特点: 2、缓存 2、安装Redis 1、安装单机版redis 2、redis-cli命令参数 3、redis的增删查改命令 4、redis的相关工具 1、介绍 redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库 redis的官网&…

摄影师危!AI绘画即将降维打击摄影行业

你还以为AI绘画影响的只是插画师行业吗&#xff1f;错了&#xff0c;摄影行业也即将面临技术洗牌 话不多说&#xff0c;先看一下这几张图 你能一眼看出这是AI画的迪丽热巴吗&#xff1f; 你是不是还以为AI绘画只能画点动漫艺术风格&#xff1f;那你就低估了AI的发展速度&…