2020-03-26

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Vuex的知識點



1.vuex是什么?

Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式紧卒。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化亲澡。Vuex 也集成到 Vue 的官方調(diào)試工具?devtools extension唉地,提供了諸如零配置的 time-travel 調(diào)試、狀態(tài)快照導(dǎo)入導(dǎo)出等高級調(diào)試功能岳守。

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

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

state碌冶,驅(qū)動應(yīng)用的數(shù)據(jù)源湿痢;

view,以聲明方式將?state?映射到視圖扑庞;

actions譬重,響應(yīng)在?view?上的用戶輸入導(dǎo)致的狀態(tài)變化。

2.State

2.1單一狀態(tài)樹

Vuex 使用單一狀態(tài)樹——是的罐氨,用一個對象就包含了全部的應(yīng)用層級狀態(tài)臀规。至此它便作為一個“唯一數(shù)據(jù)源 (SSOT)”而存在。這也意味著栅隐,每個應(yīng)用將僅僅包含一個 store 實例塔嬉。單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過程中也能輕易地取得整個當前應(yīng)用狀態(tài)的快照租悄。

單狀態(tài)樹和模塊化并不沖突——在后面的章節(jié)里我們會討論如何將狀態(tài)和狀態(tài)變更事件分布到各個子模塊中谨究。

存儲在 Vuex 中的數(shù)據(jù)和 Vue 實例中的?data?遵循相同的規(guī)則,例如狀態(tài)對象必須是純粹 (plain) 的

2.2在 Vue 組件中獲得 Vuex 狀態(tài)

那么我們?nèi)绾卧?Vue 組件中展示狀態(tài)呢恰矩?由于 Vuex 的狀態(tài)存儲是響應(yīng)式的记盒,從 store 實例中讀取狀態(tài)最簡單的方法就是在計算屬性中返回某個狀態(tài):

創(chuàng)建一個 Counter 組件constCounter={template:`

<div>{{ count }}</div>`,

computed:{count(){returnstore.state.count}}}

2.3mapState?輔助函數(shù)

當一個組件需要獲取多個狀態(tài)時候,將這些狀態(tài)都聲明為計算屬性會有些重復(fù)和冗余外傅。為了解決這個問題纪吮,我們可以使用?mapState?輔助函數(shù)幫助我們生成計算屬性,讓你少按幾次鍵:

對象展開運算符

mapState?函數(shù)返回的是一個對象萎胰。我們?nèi)绾螌⑺c局部計算屬性混合使用呢碾盟?通常,我們需要使用一個工具函數(shù)將多個對象合并為一個技竟,以使我們可以將最終對象傳給?computed?屬性冰肴。但是自從有了對象展開運算符,我們可以極大地簡化寫法:

computed:{localComputed(){/* ... */},

// 使用對象展開運算符將此對象混入到外部對象中...mapState({// ...})}

3Getter

3.1通過屬性訪問

Getter 會暴露為?store.getters?對象,你可以以屬性的形式訪問這些值:

store.getters.doneTodos// -> [{ id: 1, text: '...', done: true }]

2通過方法訪問

你也可以通過讓 getter 返回一個函數(shù)熙尉,來實現(xiàn)給 getter 傳參联逻。在你對 store 里的數(shù)組進行查詢時非常有用。

getters:{// ...getTodoById:(state)=>(id)=>{returnstate.todos.find(todo=>todo.id===id)}}

4 Mutation

mutation:更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation检痰。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的?事件類型 (type)?和 一個?回調(diào)函數(shù) (handler)包归。這個回調(diào)函數(shù)就是我們實際進行狀態(tài)更改的地方,

4.1對象風(fēng)格的提交方式

提交 mutation 的另一種方式是直接使用包含?type?屬性的對象:

store.commit({type:'increment',amount:10})

Mutation 需遵守 Vue 的響應(yīng)規(guī)則

既然 Vuex 的 store 中的狀態(tài)是響應(yīng)式的铅歼,那么當我們變更狀態(tài)時公壤,監(jiān)視狀態(tài)的 Vue 組件也會自動更新。這也意味著 Vuex 中的 mutation 也需要與使用 Vue 一樣遵守一些注意事項:

最好提前在你的 store 中初始化好所有所需屬性

5.Action

Action 類似于 mutation椎椰,不同在于:

Action 提交的是 mutation厦幅,而不是直接變更狀態(tài)。

Action 可以包含任意異步操作慨飘。

分發(fā) Action

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

store.dispatch('increment')

乍一眼看上去感覺多此一舉确憨,我們直接分發(fā) mutation 豈不更方便?實際上并非如此套媚,還記得?mutation 必須同步執(zhí)行這個限制么缚态?Action 就不受約束磁椒!我們可以在 action 內(nèi)部執(zhí)行異步操作:

actions:{incrementAsync({commit}){setTimeout(()=>{commit('increment')},1000)}}

6.Module

Vuex 允許我們將 store 分割成模塊(module)堤瘤。每個模塊擁有自己的 state、mutation浆熔、action本辐、getter、甚至是嵌套子模塊

constmoduleA={state:{...},mutations:{...},actions:{...},getters:{...}}

constmoduleB={state:{...},mutations:{...},actions:{...}}

conststore=newVuex.Store({modules:{a:moduleA,b:moduleB}})

7.項目結(jié)構(gòu)

Vuex 并不限制你的代碼結(jié)構(gòu)医增。但是慎皱,它規(guī)定了一些需要遵守的規(guī)則:

應(yīng)用層級的狀態(tài)應(yīng)該集中到單個 store 對象中。

提交?mutation?是更改狀態(tài)的唯一方法叶骨,并且這個過程是同步的茫多。

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

8.插件

Vuex 的 store 接受?plugins?選項忽刽,這個選項暴露出每次 mutation 的鉤子天揖。Vuex 插件就是一個函數(shù),它接收 store 作為唯一參數(shù):

constmyPlugin=store=>{// 當 store 初始化后調(diào)用store.subscribe((mutation,state)=>{// 每次 mutation 之后調(diào)用// mutation 的格式為 { type, payload }})}

8.1在插件內(nèi)提交 Mutation

在插件中不允許直接修改狀態(tài)——類似于組件跪帝,只能通過提交 mutation 來觸發(fā)變化今膊。

9.嚴格模式

開啟嚴格模式,僅需在創(chuàng)建 store 的時候傳入?strict: true:

conststore=newVuex.Store({// ...strict:true})

在嚴格模式下伞剑,無論何時發(fā)生了狀態(tài)變更且不是由 mutation 函數(shù)引起的斑唬,將會拋出錯誤。這能保證所有的狀態(tài)變更都能被調(diào)試工具跟蹤到。

9.2開發(fā)環(huán)境與發(fā)布環(huán)境

不要在發(fā)布環(huán)境下啟用嚴格模式恕刘!嚴格模式會深度監(jiān)測狀態(tài)樹來檢測不合規(guī)的狀態(tài)變更——請確保在發(fā)布環(huán)境下關(guān)閉嚴格模式缤谎,以避免性能損失。

類似于插件褐着,我們可以讓構(gòu)建工具來處理這種情況:

conststore=newVuex.Store({// ...strict:process.env.NODE_ENV!=='production'})

10表單處理

當在嚴格模式中使用 Vuex 時弓千,在屬于 Vuex 的 state 上使用?v-model?會比較棘手:

<inputv-model="obj.message">

假設(shè)這里的?obj?是在計算屬性中返回的一個屬于 Vuex store 的對象,在用戶輸入時献起,v-model?會試圖直接修改?obj.message洋访。在嚴格模式中,由于這個修改不是在 mutation 函數(shù)中執(zhí)行的, 這里會拋出一個錯誤谴餐。

用“Vuex 的思維”去解決這個問題的方法是:給?<input>?中綁定 value姻政,然后偵聽?input?或者?change?事件,在事件回調(diào)中調(diào)用一個方法:

<input:value="message"@input="updateMessage">

...computed:{...mapState({message:state=>state.obj.message})},methods:{updateMessage(e){this.$store.commit('updateMessage',e.target.value)}}

下面是 mutation 函數(shù):

...mutations:{updateMessage(state,message){state.obj.message=message}}

雙向綁定的計算屬性

必須承認岂嗓,這樣做比簡單地使用“v-model?+ 局部狀態(tài)”要啰嗦得多汁展,并且也損失了一些?v-model?中很有用的特性。另一個方法是使用帶有 setter 的雙向綁定計算屬性:

<inputv-model="message">

...computed:{message:{get(){returnthis.$store.state.obj.message},set(value){this.$store.commit('updateMessage',value)}}}

11測試

1測試 Mutation

Mutation 很容易被測試厌殉,因為它們僅僅是一些完全依賴參數(shù)的函數(shù)食绿。這里有一個小技巧,如果你在?store.js?文件中定義了 mutation公罕,并且使用 ES2015 模塊功能默認輸出了 Vuex.Store 的實例器紧,那么你仍然可以給 mutation 取個變量名然后把它輸出去:

conststate={...}// `mutations` 作為命名輸出對象exportconstmutations={...}exportdefaultnewVuex.Store({state,mutations})

2測試 Action

Action 應(yīng)對起來略微棘手,因為它們可能需要調(diào)用外部的 API楼眷。當測試 action 的時候铲汪,我們需要增加一個 mocking 服務(wù)層——例如,我們可以把 API 調(diào)用抽象成服務(wù)罐柳,然后在測試文件中用 mock 服務(wù)回應(yīng) API 調(diào)用掌腰。

3測試 Getter

如果你的 getter 包含很復(fù)雜的計算過程,很有必要測試它們张吉。Getter 的測試與 mutation 一樣直截了當齿梁。

測試一個 getter 的示例:

// getters.jsexportconstgetters={filteredProducts(state,{filterCategory}){returnstate.products.filter(product=>{returnproduct.category===filterCategory})}}

12熱重載

1使用 webpack 的?,Vuex 支持在開發(fā)過程中熱重載 mutation肮蛹、module勺择、action 和 getter。你也可以在 Browserify 中使用?插件蔗崎。

importVuefrom'vue'importVuexfrom'vuex'importmutationsfrom'./mutations'importmoduleAfrom'./modules/a'Vue.use(Vuex)conststate={...}conststore=newVuex.Store({state,mutations,modules:{a:moduleA}})if(module.hot){// 使 action 和 mutation 成為可熱重載模塊module.hot.accept(['./mutations','./modules/a'],()=>{// 獲取更新后的模塊// 因為 babel 6 的模塊編譯格式問題酵幕,這里需要加上 `.default`constnewMutations=require('./mutations').defaultconstnewModuleA=require('./modules/a').default// 加載新模塊store.hotUpdate({mutations:newMutations,modules:{a:newModuleA}})})}


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市缓苛,隨后出現(xiàn)的幾起案子芳撒,更是在濱河造成了極大的恐慌邓深,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笔刹,死亡現(xiàn)場離奇詭異芥备,居然都是意外死亡,警方通過查閱死者的電腦和手機舌菜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門萌壳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人日月,你說我怎么就攤上這事袱瓮。” “怎么了爱咬?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵尺借,是天一觀的道長。 經(jīng)常有香客問我精拟,道長燎斩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任蜂绎,我火速辦了婚禮栅表,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘师枣。我一直安慰自己怪瓶,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布坛吁。 她就那樣靜靜地躺著劳殖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拨脉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天宣增,我揣著相機與錄音玫膀,去河邊找鬼。 笑死爹脾,一個胖子當著我的面吹牛帖旨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灵妨,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼解阅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泌霍?” 一聲冷哼從身側(cè)響起货抄,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蟹地,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體积暖,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年怪与,在試婚紗的時候發(fā)現(xiàn)自己被綠了夺刑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡分别,死狀恐怖遍愿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耘斩,我是刑警寧澤错览,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站煌往,受9級特大地震影響倾哺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜刽脖,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一羞海、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧曲管,春花似錦却邓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至檬某,卻和暖如春撬腾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恢恼。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工抑淫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蕉拢,地道東北人弥虐。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓挽鞠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親漏隐。 傳聞我的和親對象是個殘疾皇子喧半,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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

  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統(tǒng)中,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 2,926評論 0 7
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 339評論 0 0
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 726評論 0 3
  • 習(xí)慣養(yǎng)成很容易青责,戒掉卻很難M荨H【摺! 什么是Vuex吴菠? Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式...
    前端又又閱讀 2,742評論 0 1
  • State 單一狀態(tài)樹 Vuex 使用單一狀態(tài)樹——是的者填,用一個對象就包含了全部的應(yīng)用層級狀態(tài)。至此它便作為一個“...
    peng凱閱讀 687評論 2 0