Vuex 模块化与项目实例 (2.0)
Vuex 強(qiáng)調(diào)使用單一狀態(tài)樹(shù),即在一個(gè)項(xiàng)目里只有一個(gè) store,這個(gè) store 集中管理了項(xiàng)目中所有的數(shù)據(jù)以及對(duì)數(shù)據(jù)的操作行為。但是這樣帶來(lái)的問(wèn)題是 store 可能會(huì)非常臃腫龐大不易維護(hù),所以就需要對(duì)狀態(tài)樹(shù)進(jìn)行模塊化的拆分。
?
首先貼出一個(gè)邏輯比較復(fù)雜的H5項(xiàng)目:DEMO?&?源碼
該項(xiàng)目主要包括 banner、feeds、profile 三個(gè)部分。其中 feeds 模塊最復(fù)雜,需要對(duì)數(shù)據(jù)列表進(jìn)行處理,如果單條數(shù)據(jù)中是圖片:1張按照屏幕寬展示;2張各占50%;3張以上采用九宮格形式展示;如果單條數(shù)據(jù)是視頻,則顯示播放按鈕,播放一條視頻時(shí),其他視頻暫停。
由于該項(xiàng)目數(shù)據(jù)、交互較多,我們使用 Vuex 對(duì)數(shù)據(jù)進(jìn)行托管,只在 Vue 組件中保留最基本的操作。
如果不使用 Vuex,許多數(shù)據(jù)流需要通過(guò) props 的方便向下傳遞,十分不便,尤其是一些跨組件的操作更加困難。使用 Vuex 后就可以將數(shù)據(jù)與操作保留在 store 中,每個(gè)組件都能輕松調(diào)用。
本項(xiàng)目中除了根 store 以外,還通過(guò) module 將各組件的 store 分開(kāi)管理,還不了解的同學(xué)可以往下看。
?
Module
首先介紹下基本的組件化規(guī)則:你可以根據(jù)項(xiàng)目組件的劃分來(lái)拆分 store,每個(gè)模塊里管理著當(dāng)前組件的狀態(tài)以及行為,最后將這些模塊在根 store 進(jìn)行組合。
const moduleA = {state: { ... },getters: { ... }mutations: { ... } };const moduleB = {state: { ... },getters: { ... },mutations: { ... },actions: { ... } };const store = new Vuex.Store({modules: {a: moduleA,b: moduleB} });console.log(store.state.a); // moduleA 的 state接下來(lái)看 Vuex 核心在模塊化后的使用注意事項(xiàng)。
請(qǐng)參考上文?Vuex 核心知識(shí) (2.0)
?
State
在 Vuex 模塊化中,state 是唯一會(huì)根據(jù)組合時(shí)模塊的別名來(lái)添加層級(jí)的,后面的 getters、mutations 以及 actions 都是直接合并在 store 下。
例如,訪問(wèn)模塊 a 中的 state,要通過(guò) store.state.a,訪問(wèn)根 store 上申明的 state,依然是通過(guò) store.state.xxx 直接訪問(wèn)。
const moduleA = {state: {maState: 'A'} };const moduleB = {state: {mbState: 'B'} };const store = new Vuex.Store({modules: {a: moduleA,b: moduleB},state: {rtState: 'Root'} });console.log(store.state.a.maState); // A console.log(store.state.b.mbState); // B console.log(store.state.rtState); // Root?
Getters
與 state 不同的是,不同模塊的 getters 會(huì)直接合并在 store.getters 下
const moduleA = {state: {count: 1},getters: {maGetter(state, getters, rootState) {return state.count + rootState.b.count;}} };const moduleB = {state: {count: 2},getters: {mbGetter() {return 'Hello Vuex';}} };const store = {modules: {a: moduleA,b: moduleB} };console.log(store.getters.maGetter); // 3 console.log(store.getters.mbGetter); // Hello Vuex在上文我們介紹過(guò) getters 的回調(diào)函數(shù)所接收的前兩個(gè)參數(shù),模塊化后需要用到第三個(gè)參數(shù)——rootState。參數(shù): 1. state,模塊中的 state 僅為模塊自身中的 state;2. getters,等同于 store.getters;3. rootState,全局 state。
通過(guò) rootState,模塊中的 getters 就可以引用別的模塊中的 state 了,十分方便。
注意:由于 getters 不區(qū)分模塊,所以不同模塊中的 getters 如果重名,Vuex 會(huì)報(bào)出 'duplicate getter key: [重復(fù)的getter名]' 錯(cuò)誤。
?
Mutations
mutations 與 getters 類似,不同模塊的 mutation 均可以通過(guò) store.commit 直接觸發(fā)。
const moduleA = {state: {count: 1},mutations: {sayCountA(state) {console.log('Module A count: ', state.count);}} };const moduleB = {state: {count: 2},mutations: {sayCountB(state) {console.log('Module B count: ', state.count);}} };const store = {modules: {a: moduleA,b: moduleB} };store.commit('sayCountA'); // Module A count: 1 store.commit('sayCountB'); // Module B count: 2?mutation 的回調(diào)函數(shù)中只接收唯一的參數(shù)——當(dāng)前模塊的 state。如果不同模塊中有同名的 mutation,Vuex 不會(huì)報(bào)錯(cuò),通過(guò) store.commit 調(diào)用,會(huì)依次觸發(fā)所有同名 mutation。
?
Actions
與 mutations 類似,不同模塊的 actions 均可以通過(guò) store.dispatch 直接觸發(fā)。
const moduleA = {state: {count: 1},mutations: {sayCountA(state) {console.log('Module A count: ', state.count);}},actions: {maAction(context) {context.dispatch('mbAction');}} };const moduleB = {state: {count: 2},mutations: {sayCountB(state, num) {console.log('Module B count: ', state.count+num);}},action: {mbAction({ commit, rootState }) {commit('sayCountA');commit('sayCountB', rootState.a.count);}} };const store = {modules: {a: moduleA,b: moduleB} };store.dispatch('maAction'); // Module A count: 1、Module B count: 3從上例可以看出,action 的回調(diào)函數(shù)接收一個(gè) context 上下文參數(shù),context 包含:1. state、2. rootState、3. getters、4. mutations、5. actions 五個(gè)屬性,為了簡(jiǎn)便可以在參數(shù)中解構(gòu)。
在 action 中可以通過(guò) context.commit 跨模塊調(diào)用 mutation,同時(shí)一個(gè)模塊的 action 也可以調(diào)用其他模塊的 action。
同樣的,當(dāng)不同模塊中有同名 action 時(shí),通過(guò) store.dispatch 調(diào)用,會(huì)依次觸發(fā)所有同名 actions。
?
最后有一點(diǎn)要注意的是,將 store 中的 state 綁定到 Vue 組件中的 computed 計(jì)算屬性后,對(duì) state 進(jìn)行更改需要通過(guò) mutation 或者 action,在 Vue 組件中直接進(jìn)行賦值 (this.myState = 'ABC') 是不會(huì)生效的。
?
感謝你的瀏覽,希望能有所幫助。
轉(zhuǎn)載于:https://www.cnblogs.com/libin-1/p/6400936.html
總結(jié)
以上是生活随笔為你收集整理的Vuex 模块化与项目实例 (2.0)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: FB面经Prepare: Dot Pro
- 下一篇: vue.js的认知