本文主要介紹父->子串慰、子->父、兄弟組件間施逾、跨級(jí)組件間的傳值方式。
一例获、props【父->子】
在父組件頁(yè)面使用v-bind: 或 :
將數(shù)據(jù)傳遞給子組件汉额,子組件通過(guò)props
獲取父組件傳遞過(guò)來(lái)的值。
二榨汤、$attrs【父->子】
多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí)蠕搜,通常使用的方法是通過(guò)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)單來(lái)說(shuō)岖免,使用interitAttrs: false
子組件的$attrs不會(huì)被當(dāng)做是html屬性渲染到根元素上,防止修改html同名屬性照捡。
三颅湘、$emit【子->父】
在子組件頁(yè)面使用this.$emit('自定義事件名', 數(shù)據(jù));
將數(shù)據(jù)傳遞給父組件,父組件通過(guò)@自定義事件名="事件處理方法名"
或者v-on:自定義事件名="事件處理方法名"
獲取子組件傳遞過(guò)來(lái)的值栗精。
四闯参、$listeners【子->父】
1. 簡(jiǎn)介
2. 使用
若公共組件被很多組件調(diào)用且拋出的自定義事件都不同,此時(shí)就可以使用$listeners
悲立;根據(jù)父組件調(diào)用的事件去決定拋出哪個(gè)自定義事件鹿寨。
五、EventBus【父->子薪夕、子->父脚草、兄弟組件間、跨級(jí)組件間】
1.簡(jiǎn)介
EventBus
又稱(chēng)為事件總線(xiàn)原献。在Vue中可以使用 EventBus 來(lái)作為溝通橋梁的概念馏慨,就像是所有組件共用相同的事件中心埂淮,可以向該中心注冊(cè)發(fā)送事件或接收事件,所以組件都可以上下平行地通知其他組件写隶,但也就是太方便所以若使用不慎倔撞,就會(huì)造成難以維護(hù)的災(zāi)難,因此才需要更完善的Vuex作為狀態(tài)管理中心樟澜,將通知的概念上升到共享狀態(tài)層次误窖。更多EventBus
2. 使用
-
main.js
中引入EventBus(見(jiàn)圖5-1) - 父組件中監(jiān)聽(tīng)并解綁事件(見(jiàn)圖5-2)
-
son組件中發(fā)送事件(見(jiàn)圖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í)毒费,必須通過(guò)Mutation進(jìn)行丙唧,Mutation同時(shí)提供了訂閱者模式供外部插件調(diào)用獲取State數(shù)據(jù)的更新。而當(dāng)所有異步操作(常見(jiàn)于調(diào)用后端接口異步獲取更新數(shù)據(jù))或批量的同步操作需要走Action觅玻,但Action也是無(wú)法直接修改State的想际,還是需要通過(guò)Mutation來(lái)修改State的數(shù)據(jù)。最后溪厘,根據(jù)State的變化胡本,渲染到視圖上。
2. 模塊介紹
- Vue Components:Vue組件畸悬。HTML頁(yè)面上侧甫,負(fù)責(zé)接收用戶(hù)操作等交互行為,執(zhí)行
dispatch
方法觸發(fā)對(duì)應(yīng)action進(jìn)行回應(yīng)蹋宦。 - dispatch:操作行為觸發(fā)方法披粟,是唯一能執(zhí)行
action
的方法。 - actions:操作行為處理模塊,由組件中的
$store.dispatch('action 名稱(chēng)', data1)
來(lái)觸發(fā)冷冗。然后由commit()來(lái)觸發(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 名稱(chēng)')
來(lái)觸發(fā)。是Vuex修改state的唯一推薦方法课兄。該方法只能進(jìn)行同步操作牍氛,且方法名只能全局唯一。操作之中會(huì)有一些hook暴露出來(lái)烟阐,以進(jìn)行state的監(jiān)控等搬俊。 - state:頁(yè)面狀態(tài)管理容器對(duì)象。集中存儲(chǔ)Vue components中data對(duì)象的零散數(shù)據(jù)蜒茄,全局唯一唉擂,以進(jìn)行統(tǒng)一的狀態(tài)管理。頁(yè)面顯示所需的數(shù)據(jù)從該對(duì)象中進(jìn)行讀取檀葛,利用Vue的細(xì)粒度數(shù)據(jù)響應(yīng)機(jī)制來(lái)進(jìn)行高效的狀態(tài)更新玩祟。
- getters:state對(duì)象讀取方法。圖中沒(méi)有單獨(dú)列出該模塊屿聋,應(yīng)該被包含在了render中空扎,Vue Components通過(guò)該方法讀取全局state對(duì)象。
3. 解決vuex刷新?tīng)顟B(tài)消失問(wèn)題
-
第一種方法:使用localStorage/sessionSorage存儲(chǔ)vuex數(shù)據(jù)
圖6-2 - 第二種方法(推薦):
vuex-persistedstate
安裝:npm install --save vuex-persistedstate
import Vuex from 'vuex';
// 解決刷新瀏覽器润讥,數(shù)據(jù)消失問(wèn)題
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è)依賴(lài),不論組件層次有多深勒魔,并在其上下游關(guān)系成立的時(shí)間里始終生效甫煞。如果你熟悉 React,這與 React 的上下文特性很相似冠绢。
provide / inject API 主要解決了跨級(jí)組件間的通信問(wèn)題抚吠。官網(wǎng)提供了很詳細(xì)的介紹,這里直接上圖
2. 使用
- 由父組件向其下的所有子組件(所有子組件指:兒子弟胀、孫子楷力、曾孫等等)注入user數(shù)據(jù)(見(jiàn)圖7-2)
- 子組件son向其下的所有子組件(所有子組件指:兒子、孫子孵户、曾孫等等)注入sonUser數(shù)據(jù)(見(jiàn)圖7-3)
-
再孫子組件grandSon中獲取父組件的user數(shù)據(jù)和子組件的sonUser數(shù)據(jù)(見(jiàn)圖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è)過(guò)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è)過(guò)的對(duì)象
九、sessionStorage阿弃、localStorage【父-> 子诊霹、子->父、兄弟組件間渣淳、跨級(jí)組件間】
sessionStorage脾还、localStorage也能實(shí)現(xiàn)通信,但是需要監(jiān)聽(tīng)storage的變化入愧,如何監(jiān)聽(tīng)storage的變化鄙漏,之前有寫(xiě)過(guò)這篇文章vue 監(jiān)聽(tīng)localStorage、sessionStorage變化棺蛛,這里就不贅述了怔蚌。
總結(jié)
1. 父 -> 子 間的通信
- props
- $attrs
- provide/inject
- $children
- $refs
- EventBus
- sessionStorage/localStorage + storage監(jiān)聽(tīng)
2. 子 -> 父 間的通信
- $emit
- $listeners
- EventBus
- $parent
- sessionStorage/localStorage + storage監(jiān)聽(tīng)
3. 兄弟組件間的通信
- EventBus
- vuex
- sessionStorage/localStorage + storage監(jiān)聽(tīng)
4. 跨級(jí)組件間的通信
- EventBus
- vuex
- provide/inject
- sessionStorage/localStorage + storage監(jiān)聽(tīng)