Vuex學(xué)習(xí)筆記

參考資料:

https://vuex.vuejs.org/zh/

https://scrimba.com/g/gvuex

https://juejin.im/post/59097cd7a22b9d0065fb61d2


Vuex是一個(gè)專門(mén)為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化婶芭。

什么是“狀態(tài)管理模式”牢裳?

一個(gè)狀態(tài)自管理應(yīng)用包含以下幾個(gè)部分:

state:驅(qū)動(dòng)應(yīng)用的數(shù)據(jù)源

view:以聲明方式將state映射到視圖

action:響應(yīng)在view上的用戶輸入導(dǎo)致的狀態(tài)變化

當(dāng)我們的應(yīng)用遇到多個(gè)組件共享狀態(tài)時(shí),例如:

1. 多個(gè)視圖依賴于同一狀態(tài)隆檀。傳參的方法對(duì)于多層嵌套的組件會(huì)非常繁瑣摇天,并且無(wú)法在兄弟組件中傳遞狀態(tài)。

2. 來(lái)自不同視圖的行為需要變更同一狀態(tài)恐仑。采用父子組件或者通過(guò)事件來(lái)變更和同步狀態(tài)的多份拷貝泉坐。

上面的方法都非常脆弱,會(huì)導(dǎo)致代碼難以維護(hù)裳仆,于是想到把組件的共享狀態(tài)抽取出來(lái)腕让,以一個(gè)全局單一實(shí)例的模式來(lái)管理。這樣應(yīng)用的組件就構(gòu)成了一個(gè)巨大的“視圖”樹(shù)歧斟,不管組件位于樹(shù)的那個(gè)位置纯丸,都可以獲取狀態(tài)和觸發(fā)行為,這就是Vuex的基本思想静袖。Vuex是專門(mén)為Vue.js設(shè)計(jì)的狀態(tài)管理庫(kù)觉鼻,以利用Vue.js的細(xì)顆粒度數(shù)據(jù)響應(yīng)機(jī)制來(lái)進(jìn)行高效的狀態(tài)更新。

使用vuex的vue項(xiàng)目結(jié)構(gòu)

每一個(gè)Vuex應(yīng)用的核心就是store倉(cāng)庫(kù)队橙,store就像一個(gè)容器坠陈,它包含著應(yīng)用中大部分的狀態(tài)state。但是Vuex和單純的全局對(duì)象又一下不同:

1. Vuex的狀態(tài)存儲(chǔ)是響應(yīng)式的喘帚。當(dāng)vue組件從store中讀取狀態(tài)的時(shí)候畅姊,若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)高效跟新吹由。

2. 不能直接得改變store中的狀態(tài)若未,只有顯示地提交commit mutation才能改變store中的狀態(tài)值。這樣就可以跟蹤每一個(gè)狀態(tài)的變化倾鲫。

Vuex使用“單一狀態(tài)樹(shù)”粗合,用一個(gè)對(duì)象就包含了全部的應(yīng)用層級(jí)狀態(tài)。每一個(gè)應(yīng)用只包含一個(gè)store實(shí)例乌昔,是整個(gè)應(yīng)用的“唯一數(shù)據(jù)源”隙疚。單一狀態(tài)樹(shù)讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過(guò)程中也能輕易地取得整個(gè)當(dāng)前應(yīng)用狀態(tài)的快照磕道。

Vuex通過(guò)store選項(xiàng)供屉,提供了一種機(jī)制將狀態(tài)從根組件注入到每個(gè)子組件中。在根實(shí)例中注冊(cè)Store選項(xiàng),該store實(shí)例會(huì)注入到根組件下的所有子組件中伶丐,且子組件能通過(guò)this.$store訪問(wèn)到悼做。

在根實(shí)例中注冊(cè)store
在子組件中訪問(wèn)this.$store

當(dāng)一個(gè)組件需要獲取多個(gè)狀態(tài)的時(shí)候,將這些狀態(tài)都聲明為計(jì)算屬性會(huì)有些重復(fù)和冗余哗魂,這時(shí)可以使用mapState輔助函數(shù)幫助我們生產(chǎn)計(jì)算屬性肛走,將html組件中需要的狀態(tài)和store中的狀態(tài)對(duì)應(yīng)起來(lái)。

定義全局狀態(tài)的count
使用輔助函數(shù)mapState返回多個(gè)狀態(tài)

當(dāng)映射的計(jì)算屬性的名稱與state的子節(jié)點(diǎn)名稱相同時(shí)录别,可以給mapState傳一個(gè)字符串?dāng)?shù)組:

定義全局狀態(tài)值
使用mapState函數(shù)將組件需要的狀態(tài)值和全局狀態(tài)值作映射

Vuex允許在store中定義getter朽色,可以認(rèn)為是store的計(jì)算屬性。getter的返回值會(huì)根據(jù)它的依賴被緩存起來(lái)组题,只有當(dāng)它的依賴值發(fā)生改變才會(huì)被重新計(jì)算葫男。這樣getter中定義的函數(shù)就可以被多個(gè)組件調(diào)用。

Getter會(huì)暴露為store.getters對(duì)象往踢,可以以屬性的形式訪問(wèn)腾誉,也可以接受其他getter作為第二個(gè)參數(shù)。還可以通過(guò)讓getter返回一個(gè)函數(shù)峻呕,來(lái)實(shí)現(xiàn)給getter傳參數(shù)利职,在種方法在對(duì)數(shù)組進(jìn)行查詢時(shí)非常有用(getter 在通過(guò)方法訪問(wèn)時(shí),每次都會(huì)去進(jìn)行調(diào)用瘦癌,而不會(huì)緩存結(jié)果猪贪。):

在store中定義getter
在組件中使用store的getter

mapGetters輔助函數(shù)也是將store中的getter映射到局部計(jì)算屬性:

當(dāng)映射的計(jì)算屬性的名稱與getter屬性名稱相同時(shí)
給getter屬性取一個(gè)別名

更改Vuex的store中的狀態(tài)的唯一方法是提交mutation。Vuex中的mutation類似于事件:每個(gè)mutation都有一個(gè)字符串的事件類型(type)和一個(gè)回調(diào)函數(shù)(handler)讯私。利用回調(diào)函數(shù)更改狀態(tài)热押,state作為第一個(gè)參數(shù)。mutation handler是不能直接調(diào)用的斤寇,需要以相應(yīng)的type調(diào)用store.commit方法注冊(cè)事件:“當(dāng)觸發(fā)一個(gè)類型為increment的mutation時(shí)桶癣,調(diào)用這個(gè)回調(diào)函數(shù)”。

通過(guò)commit increment事件娘锁,改變state屬性值

mutation的載荷payload是指向store.commit傳入的額外參數(shù)牙寞,載荷應(yīng)該是一個(gè)對(duì)象。提交mutation的另一種方式是直接使用包含type屬性的對(duì)象莫秆。當(dāng)使用對(duì)象風(fēng)格的提交方式间雀,整個(gè)對(duì)象都作為載荷傳給mutation函數(shù),因此回調(diào)函數(shù)handler就可以保持不變:

直接傳入?yún)?shù)
使用包含type屬性的對(duì)象作為載荷

Vuex的store中的狀態(tài)是響應(yīng)式的镊屎,那么當(dāng)我們變更狀態(tài)時(shí)惹挟,監(jiān)視狀態(tài)的vue組件也會(huì)自動(dòng)更新。mutation需要遵守vue的響應(yīng)規(guī)則:

1. 最好提前在你的store中初始化好需要的屬性缝驳。

2. 當(dāng)需要在對(duì)象上添加新屬性時(shí)连锯,有2種方式:

? ? a.使用 Vue.set(obj, 'newProp', 123)

? ? b. 以新對(duì)象替換老對(duì)象:state.obj = {...state.obj, newProp:123}


添加一個(gè)按鈕归苍,點(diǎn)擊一次加1

code
WebUI

使用mapMutations輔助函數(shù)將組件的methods中的方法映射到store.commit調(diào)用:

輔助函數(shù)將組件中的methods映射為store.commit

mutation 都是同步事務(wù)。mutation必須是同步函數(shù)运怖。如果我們正在debug一個(gè)app并且觀察devtool中的mutation日志霜医。每一條mutation被記錄,devtools都需要捕捉到前一狀態(tài)和后一狀態(tài)的快照驳规。然而,mutation 中的異步函數(shù)中的回調(diào)讓這不可能完成:因?yàn)楫?dāng) mutation 觸發(fā)的時(shí)候署海,回調(diào)函數(shù)還沒(méi)有被調(diào)用吗购,devtools 不知道什么時(shí)候回調(diào)函數(shù)實(shí)際上被調(diào)用——實(shí)質(zhì)上任何在回調(diào)函數(shù)中進(jìn)行的狀態(tài)的改變都是不可追蹤的。

Action類似于mutation砸狞。不同處在于:

1. action提交的是mutation捻勉,而不是直接變更狀態(tài)

2. action可以包含任意異步操作


Action通過(guò)store.dispatch方法觸發(fā):

使用dispatch觸發(fā)action回調(diào)函數(shù)

Actions同樣支持載荷方式和對(duì)象方式進(jìn)行分發(fā):

載荷方式進(jìn)行分發(fā)
對(duì)象方式進(jìn)行分發(fā)

在組件中使用this.$store.dispath('actionName')來(lái)分發(fā)action,或者使用mapAction輔助函數(shù)將組件中的methods映射為store.dispatch調(diào)用:

mapAction輔助函數(shù)

Action組合使用:

此處需要先學(xué)習(xí)JS的異步函數(shù) :

http://www.reibang.com/writer#/notebooks/37007324/notes/47700732

store.dispatch可以處理被觸發(fā)的action的處理函數(shù)返回的Promise刀森,并且store.dispatch仍舊返回Promise踱启。


當(dāng)app的所有狀態(tài)都集中到一個(gè)store對(duì)象中,store會(huì)變的相當(dāng)臃腫研底。vuex允許我們將store分割成模塊module埠偿。每個(gè)模塊擁有自己的state,mutation榜晦,action冠蒋,getter:

store module

Vue項(xiàng)目結(jié)構(gòu)通用規(guī)則:

vue項(xiàng)目結(jié)構(gòu)

1. 應(yīng)用層級(jí)的狀態(tài)應(yīng)該集中到單個(gè)store對(duì)象中。

2.提交mutation是更改狀態(tài)的唯一方法乾胶,這個(gè)過(guò)程是同步的抖剿。

3.異步邏輯都應(yīng)該封裝到action里面。

4.如果store文件太大识窿,可以將action斩郎,mutation和getter分割到單獨(dú)的文件中。


插件plugin

Vuex的store接受plugins選項(xiàng)喻频,這個(gè)選項(xiàng)暴露出每次mutation的鉤子缩宜。Vuex插件就是一個(gè)函數(shù),它接受store作為唯一參數(shù):

vuex plugins的使用

插件中需要提交mutation來(lái)改變store的狀態(tài)值半抱,所以插件可以用來(lái)同步數(shù)據(jù)源到store脓恕。


嚴(yán)格模式

在創(chuàng)建store的時(shí)候傳入strict:true就開(kāi)啟嚴(yán)了格模式,無(wú)論何時(shí)發(fā)生了不是由mutation函數(shù)引起的狀態(tài)變更窿侈,就會(huì)拋出錯(cuò)誤炼幔。不要在發(fā)布環(huán)境下啟用嚴(yán)格模式!嚴(yán)格模式會(huì)深度監(jiān)測(cè)狀態(tài)樹(shù)來(lái)檢測(cè)不合規(guī)的狀態(tài)變更——請(qǐng)確保在發(fā)布環(huán)境下關(guān)閉嚴(yán)格模式史简,以避免性能損失乃秀。

根據(jù)env開(kāi)啟嚴(yán)格模式

使用vuex的思維處理表單:

給?<input>?中綁定 value肛著,然后偵聽(tīng)?input?或者?change?事件,在事件回調(diào)中調(diào)用 action:


熱重載:

使用 webpack 的?Hot Module Replacement API跺讯,Vuex 支持在開(kāi)發(fā)過(guò)程中熱重載 mutation枢贿、module、action 和 getter刀脏。對(duì)于 mutation 和模塊局荚,你需要使用?store.hotUpdate()?方法:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市愈污,隨后出現(xiàn)的幾起案子耀态,更是在濱河造成了極大的恐慌,老刑警劉巖暂雹,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件首装,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡杭跪,警方通過(guò)查閱死者的電腦和手機(jī)仙逻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涧尿,“玉大人系奉,你說(shuō)我怎么就攤上這事」昧” “怎么了喜最?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)庄蹋。 經(jīng)常有香客問(wèn)我瞬内,道長(zhǎng),這世上最難降的妖魔是什么限书? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任虫蝶,我火速辦了婚禮,結(jié)果婚禮上倦西,老公的妹妹穿的比我還像新娘能真。我一直安慰自己,他們只是感情好扰柠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布粉铐。 她就那樣靜靜地躺著,像睡著了一般卤档。 火紅的嫁衣襯著肌膚如雪蝙泼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天劝枣,我揣著相機(jī)與錄音汤踏,去河邊找鬼织鲸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛溪胶,可吹牛的內(nèi)容都是我干的搂擦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哗脖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瀑踢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起才避,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丘损,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后工扎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衔蹲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年肢娘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舆驶。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡橱健,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沙廉,到底是詐尸還是另有隱情拘荡,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布撬陵,位于F島的核電站珊皿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巨税。R本人自食惡果不足惜蟋定,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望草添。 院中可真熱鬧驶兜,春花似錦、人聲如沸远寸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驰后。三九已至肆资,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灶芝,已是汗流浹背迅耘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工贱枣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颤专。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓纽哥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親栖秕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子春塌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • vuex學(xué)習(xí)筆記 vuex是什么? Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式簇捍。它采用集中式存...
    EL_PSY_CONGROO閱讀 770評(píng)論 0 0
  • Vuex 是什么只壳? ** 官方解釋:Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式**。它采用集中...
    Rz______閱讀 2,306評(píng)論 1 10
  • vuex理解。 Vuex是一個(gè)專為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式事格。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件狀態(tài)惕艳,...
    GXW_Lyon閱讀 277評(píng)論 0 0
  • 學(xué)習(xí)目的 了解和熟練使用 VueX,能夠在實(shí)際項(xiàng)目中運(yùn)用驹愚。 VueX介紹 Vuex 是一個(gè)專為 Vue.js ...
    _1633_閱讀 2,794評(píng)論 0 7
  • vuex 狀態(tài)管理器 作為應(yīng)用中所有組件的中央儲(chǔ)存 只能以預(yù)定的方式去操作狀態(tài) 把所有組件共享的狀態(tài)抽取出來(lái)作為全...
    一只大椰子閱讀 790評(píng)論 0 1