【干貨】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.pswp.cn/diannao/35649.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35649.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35649.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

代碼隨想錄算法訓練營DAY49|300.最長遞增子序列、 674. 最長連續遞增序列、718. 最長重復子數組

300.最長遞增子序列 題目鏈接&#xff1a;300.最長遞增子序列dp初始化為1&#xff08;最小子序列長度為1&#xff09; class Solution(object):def lengthOfLIS(self, nums):""":type nums: List[int]:rtype: int"""dp [1]*len(nums)result …

leetcode-18- [669]修剪二叉搜索樹[108]將有序數組轉換為二叉搜索樹[538]把二叉搜索樹轉換為累加樹

重點&#xff1a;一般二叉樹多考慮遍歷順序&#xff0c; 二叉搜索樹多考慮特性&#xff0c;不用考慮遍歷順序。 一、[108]將有序數組轉換為二叉搜索樹 左閉右開 偶數取左邊 class Solution {public TreeNode sortedArrayToBST(int[] nums) {return traversal(nums,0, nums…

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 …

為什么不推薦使用 UUID 作為主鍵

UUID 作為主鍵的討論背景 面試官提出問題時&#xff0c;應提供具體場景&#xff0c;例如 UUID 是由日志服務器還是客戶端生成。 UUID 的優點 獨立生成&#xff1a;可以在任何地方生成&#xff0c;無需與數據庫服務器往返。簡化邏輯&#xff1a;預先生成父表主鍵值&#xff0…

使用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;如文件系統、網絡協議棧、…

[創業之路-130] :制造業企業的必備管理神器-ERP-基礎數據庫-物料類型與物料編碼

目錄 前言&#xff1a; 一、什么是物料 1、物料的定義 2、物料的分類 3、物料的性質 4. 輔助物料要放到產品的BOM中嗎&#xff1f; 二、ERP物料類型 三、ERP物料編碼 3.1 概述 3.2 示例 示例一&#xff1a;某企業冰箱材料分類與編碼 示例二&#xff1a;某機械加工廠…

行業案例 | 智能終端設備的數據基礎從哪兒來?

智能終端的快速發展讓我們在許多科幻電影中看到的“未來場景”正在一步步變為現實&#xff1a;智能家居正在解放我們的雙手&#xff0c;工業機器人讓生產效率倍增&#xff0c;智能穿戴設備讓我們便利地感知自身與外部的連結……然而&#xff0c;要想讓萬物“智聯”&#xff0c;…

主流數據同步工具對比詳解

文章目錄 概述1. Flink CDC (Apache Flink Change Data Capture)2. Debezium3. DataX4. Canal5. Sqoop6. Kettle (Pentaho Data Integration)7. Oracle GoldenGate概述 數據同步工具是企業數據開發常用的中間件,如何從眾多工具中正確選型是個問題,本文詳細介紹了主流工具的優…

從環型到樹型:多種網絡拓撲結構的優缺點及應用

網絡拓撲作為網絡設計的基礎&#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;并將其應用于各種領域&…