vue組件間通信

本文主要介紹父->子、子->父、兄弟組件間、跨級(jí)組件間的傳值方式。

一、props【父->子】

在父組件頁面使用v-bind: 或 :將數(shù)據(jù)傳遞給子組件,子組件通過props獲取父組件傳遞過來的值。

圖1-1 父組件

圖1-2 子組件

圖1-3 效果

二、$attrs【父->子】

多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí),通常使用的方法是通過vuex。但如果僅僅是傳遞數(shù)據(jù),而不做中間處理,使用 vuex 處理,未免有點(diǎn)大材小用。為此Vue2.4 版本提供了另一種方法----$attrs

1. $attrs:
圖2-1

示例:
我們向子組件son傳遞5個(gè)屬性,再由子組件son向?qū)O子組件grandson傳遞4個(gè)屬性(這4個(gè)組件不做任何處理,只是傳遞),son組件向grandson組件傳遞的那4個(gè)屬性就可以使用v-bind=$attrs

圖2-2

圖2-3
2. interitAttrs:

通常和$attrs配合使用。

圖2-4

簡(jiǎn)單來說,使用interitAttrs: false子組件的$attrs不會(huì)被當(dāng)做是html屬性渲染到根元素上,防止修改html同名屬性。

圖2-5

圖2-6

三、$emit【子->父】

在子組件頁面使用this.$emit('自定義事件名', 數(shù)據(jù));將數(shù)據(jù)傳遞給父組件,父組件通過@自定義事件名="事件處理方法名" 或者v-on:自定義事件名="事件處理方法名"獲取子組件傳遞過來的值。

圖3-1 子組件

圖3-2 父組件

圖3-3 效果

四、$listeners【子->父】

1. 簡(jiǎn)介
圖4-1
2. 使用
圖4-2

圖4-3

若公共組件被很多組件調(diào)用且拋出的自定義事件都不同,此時(shí)就可以使用$listeners;根據(jù)父組件調(diào)用的事件去決定拋出哪個(gè)自定義事件。

圖4-4

圖4-5

五、EventBus【父->子、子->父、兄弟組件間、跨級(jí)組件間】

1.簡(jiǎn)介

EventBus 又稱為事件總線。在Vue中可以使用 EventBus 來作為溝通橋梁的概念,就像是所有組件共用相同的事件中心,可以向該中心注冊(cè)發(fā)送事件或接收事件,所以組件都可以上下平行地通知其他組件,但也就是太方便所以若使用不慎,就會(huì)造成難以維護(hù)的災(zāi)難,因此才需要更完善的Vuex作為狀態(tài)管理中心,將通知的概念上升到共享狀態(tài)層次。更多EventBus

2. 使用
  • main.js中引入EventBus(見圖5-1)
  • 父組件中監(jiān)聽并解綁事件(見圖5-2)
  • son組件中發(fā)送事件(見圖5-3)


    圖5-1

    圖5-2

    圖5-3

六、vuex【兄弟組件間、跨級(jí)組件間】

vuex官網(wǎng)

1. vuex原理
圖6-1

Vuex實(shí)現(xiàn)了一個(gè)單向數(shù)據(jù)流,在全局擁有一個(gè)State存放數(shù)據(jù),當(dāng)組件要更改State中的數(shù)據(jù)時(shí),必須通過Mutation進(jìn)行,Mutation同時(shí)提供了訂閱者模式供外部插件調(diào)用獲取State數(shù)據(jù)的更新。而當(dāng)所有異步操作(常見于調(diào)用后端接口異步獲取更新數(shù)據(jù))或批量的同步操作需要走Action,但Action也是無法直接修改State的,還是需要通過Mutation來修改State的數(shù)據(jù)。最后,根據(jù)State的變化,渲染到視圖上。

2. 模塊介紹
  • Vue Components:Vue組件。HTML頁面上,負(fù)責(zé)接收用戶操作等交互行為,執(zhí)行dispatch方法觸發(fā)對(duì)應(yīng)action進(jìn)行回應(yīng)。
  • dispatch:操作行為觸發(fā)方法,是唯一能執(zhí)行action的方法。
  • actions:操作行為處理模塊,由組件中的$store.dispatch('action 名稱', data1)來觸發(fā)。然后由commit()來觸發(fā)mutation的調(diào)用 , 間接更新 state。負(fù)責(zé)處理Vue Components接收到的所有交互行為。包含同步/異步操作,支持多個(gè)同名方法,按照注冊(cè)的順序依次觸發(fā)。向后臺(tái)API請(qǐng)求的操作就在這個(gè)模塊中進(jìn)行,包括觸發(fā)其他action以及提交mutation的操作。該模塊提供了Promise的封裝,以支持action的鏈?zhǔn)接|發(fā)。
  • commit:狀態(tài)改變提交操作方法。對(duì)mutation進(jìn)行提交,是唯一能執(zhí)行mutation的方法
  • mutations:狀態(tài)改變操作方法,由actions中的commit('mutation 名稱')來觸發(fā)。是Vuex修改state的唯一推薦方法。該方法只能進(jìn)行同步操作,且方法名只能全局唯一。操作之中會(huì)有一些hook暴露出來,以進(jìn)行state的監(jiān)控等。
  • state:頁面狀態(tài)管理容器對(duì)象。集中存儲(chǔ)Vue components中data對(duì)象的零散數(shù)據(jù),全局唯一,以進(jìn)行統(tǒng)一的狀態(tài)管理。頁面顯示所需的數(shù)據(jù)從該對(duì)象中進(jìn)行讀取,利用Vue的細(xì)粒度數(shù)據(jù)響應(yīng)機(jī)制來進(jìn)行高效的狀態(tài)更新。
  • getters:state對(duì)象讀取方法。圖中沒有單獨(dú)列出該模塊,應(yīng)該被包含在了render中,Vue Components通過該方法讀取全局state對(duì)象。
3. 解決vuex刷新狀態(tài)消失問題
  • 第一種方法:使用localStorage/sessionSorage存儲(chǔ)vuex數(shù)據(jù)


    圖6-2
  • 第二種方法(推薦):vuex-persistedstate
    安裝:npm install --save vuex-persistedstate
import Vuex from 'vuex';
// 解決刷新瀏覽器,數(shù)據(jù)消失問題
import createPersistedState from 'vuex-persistedstate';
Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [createPersistedState()]
});

七、provide/inject【父 -> 子、跨級(jí)組件間】

provide / inject 官網(wǎng)介紹

1. 簡(jiǎn)介

vue2.2.0 新增API,這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在其上下游關(guān)系成立的時(shí)間里始終生效。如果你熟悉 React,這與 React 的上下文特性很相似。
provide / inject API 主要解決了跨級(jí)組件間的通信問題。官網(wǎng)提供了很詳細(xì)的介紹,這里直接上圖

圖7-1

2. 使用
  • 由父組件向其下的所有子組件(所有子組件指:兒子、孫子、曾孫等等)注入user數(shù)據(jù)(見圖7-2)
  • 子組件son向其下的所有子組件(所有子組件指:兒子、孫子、曾孫等等)注入sonUser數(shù)據(jù)(見圖7-3)
  • 再孫子組件grandSon中獲取父組件的user數(shù)據(jù)和子組件的sonUser數(shù)據(jù)(見圖7-4)。


    圖7-2 父組件

    圖7-3 子組件son

    圖7-4 孫子組件grandson

八、$parent、$children、$refs

1. 簡(jiǎn)介
  • $parent: 獲取父實(shí)例。【子 -> 父】
  • $children:當(dāng)前實(shí)例的直接子組件。需要注意 $children 并不保證順序,也不是響應(yīng)式的。【父 -> 子】
  • $refs:一個(gè)對(duì)象,持有注冊(cè)過 ref 的所有 DOM 元素和組件實(shí)例。【父 -> 子】
    $parent、$children、$refs都是直接得到組件實(shí)例,使用后可以直接調(diào)用組件的方法和數(shù)據(jù)。
2. 使用

由圖8-1可知,this.$children獲取到的是一個(gè)vue實(shí)列數(shù)組

圖8-1 $children

由圖8-2可知,this.$parent獲取到的是直接父實(shí)例

圖8-2 $parent

由圖8-3可知,this.$refs返回的是一個(gè)使用ref注冊(cè)過的對(duì)象

圖8-3 $refs

九、sessionStorage、localStorage【父-> 子、子->父、兄弟組件間、跨級(jí)組件間】

sessionStorage、localStorage也能實(shí)現(xiàn)通信,但是需要監(jiān)聽storage的變化,如何監(jiān)聽storage的變化,之前有寫過這篇文章vue 監(jiān)聽localStorage、sessionStorage變化,這里就不贅述了。

總結(jié)

1. 父 -> 子 間的通信
  • props
  • $attrs
  • provide/inject
  • $children
  • $refs
  • EventBus
  • sessionStorage/localStorage + storage監(jiān)聽
2. 子 -> 父 間的通信
  • $emit
  • $listeners
  • EventBus
  • $parent
  • sessionStorage/localStorage + storage監(jiān)聽
3. 兄弟組件間的通信
  • EventBus
  • vuex
  • sessionStorage/localStorage + storage監(jiān)聽
4. 跨級(jí)組件間的通信
  • EventBus
  • vuex
  • provide/inject
  • sessionStorage/localStorage + storage監(jiān)聽
參考文章

vue組件間通信的六種方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容