本文主要介紹父->子、子->父、兄弟組件間、跨級(jí)組件間的傳值方式。
一、props【父->子】
在父組件頁面使用v-bind: 或 :
將數(shù)據(jù)傳遞給子組件,子組件通過props
獲取父組件傳遞過來的值。
二、$attrs【父->子】
多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí),通常使用的方法是通過vuex。但如果僅僅是傳遞數(shù)據(jù),而不做中間處理,使用 vuex 處理,未免有點(diǎn)大材小用。為此Vue2.4 版本提供了另一種方法----$attrs
;
1. $attrs:
示例:
我們向子組件son傳遞5個(gè)屬性,再由子組件son向?qū)O子組件grandson傳遞4個(gè)屬性(這4個(gè)組件不做任何處理,只是傳遞),son組件向grandson組件傳遞的那4個(gè)屬性就可以使用v-bind=$attrs
。
2. interitAttrs:
通常和$attrs
配合使用。
簡(jiǎn)單來說,使用interitAttrs: false
子組件的$attrs不會(huì)被當(dāng)做是html屬性渲染到根元素上,防止修改html同名屬性。
三、$emit【子->父】
在子組件頁面使用this.$emit('自定義事件名', 數(shù)據(jù));
將數(shù)據(jù)傳遞給父組件,父組件通過@自定義事件名="事件處理方法名"
或者v-on:自定義事件名="事件處理方法名"
獲取子組件傳遞過來的值。
四、$listeners【子->父】
1. 簡(jiǎn)介
2. 使用
若公共組件被很多組件調(diào)用且拋出的自定義事件都不同,此時(shí)就可以使用$listeners
;根據(jù)父組件調(diào)用的事件去決定拋出哪個(gè)自定義事件。
五、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í)組件間】
1. vuex原理
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í)組件間】
1. 簡(jiǎn)介
vue2.2.0 新增API,這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在其上下游關(guān)系成立的時(shí)間里始終生效。如果你熟悉 React,這與 React 的上下文特性很相似。
provide / inject API 主要解決了跨級(jí)組件間的通信問題。官網(wǎng)提供了很詳細(xì)的介紹,這里直接上圖
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-2可知,this.$parent
獲取到的是直接父實(shí)例
由圖8-3可知,this.$refs
返回的是一個(gè)使用ref注冊(cè)過的對(duì)象
九、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)聽