vuex模塊化 Vuex 模塊化 (2.0)

Vuex 模塊化 (2.0)

 

Vuex 強調使用單一狀態樹,即在一個項目裏只有一個 store,這個 store 集中管理了項目中全部的數據以及對數據的操做行爲。可是這樣帶來的問題是 store 可能會很是臃腫龐大不易維護,因此就須要對狀態樹進行模塊化的拆分。html

 

首先貼出一個邏輯比較複雜的H5項目:源碼 & DEMOgit

該項目主要包括 banner、feeds、profile 三個部分。其中 feeds 模塊最複雜,須要對數據列表進行處理,若是單條數據中是圖片:1張按照屏幕寬展現;2張各佔50%;3張以上採用九宮格形式展現;若是單條數據是視頻,則顯示播放按鈕,播放一條視頻時,其餘視頻暫停。github

因爲該項目數據、交互較多,咱們使用 Vuex 對數據進行託管,只在 Vue 組件中保留最基本的操做。模塊化

若是不使用 Vuex,許多數據流須要經過 props 的方便向下傳遞,十分不便,尤爲是一些跨組件的操做更加困難。使用 Vuex 後就能夠將數據與操做保留在 store 中,每一個組件都能輕鬆調用。函數

本項目中除了根 store 之外,還經過 module 將各組件的 store 分開管理,還不瞭解的同窗能夠往下看。組件化

 

Module

首先介紹下基本的組件化規則:你能夠根據項目組件的劃分來拆分 store,每一個模塊裏管理着當前組件的狀態以及行爲,最後將這些模塊在根 store 進行組合。post

複製代碼
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
複製代碼

接下來看 Vuex 核心在模塊化後的使用注意事項。this

請參考上文 Vuex 核心知識 (2.0)url

 

State

在 Vuex 模塊化中,state 是惟一會根據組合時模塊的別名來添加層級的,後面的 getters、mutations 以及 actions 都是直接合並在 store 下。spa

例如,訪問模塊 a 中的 state,要經過 store.state.a,訪問根 store 上申明的 state,依然是經過 store.state.xxx 直接訪問。

複製代碼
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 會直接合並在 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
複製代碼

在上文咱們介紹過 getters 的回調函數所接收的前兩個參數,模塊化後須要用到第三個參數——rootState。參數: 1. state,模塊中的 state 僅爲模塊自身中的 state;2. getters,等同於 store.getters;3. rootState,全局 state。

經過 rootState,模塊中的 getters 就能夠引用別的模塊中的 state 了,十分方便。

注意:因爲 getters 不區分模塊,因此不一樣模塊中的 getters 若是重名,Vuex 會報出 'duplicate getter key: [重複的getter名]' 錯誤。

 

Mutations

mutations 與 getters 相似,不一樣模塊的 mutation 都可以經過 store.commit 直接觸發。

複製代碼
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 的回調函數中只接收惟一的參數——當前模塊的 state。若是不一樣模塊中有同名的 mutation,Vuex 不會報錯,經過 store.commit 調用,會依次觸發全部同名 mutation。

 

Actions

與 mutations 相似,不一樣模塊的 actions 都可以經過 store.dispatch 直接觸發。

複製代碼
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: 一、Module B count: 3
複製代碼

從上例能夠看出,action 的回調函數接收一個 context 上下文參數,context 包含:1. state、2. rootState、3. getters、4. mutations、5. actions 五個屬性,爲了簡即可以在參數中解構。

在 action 中能夠經過 context.commit 跨模塊調用 mutation,同時一個模塊的 action 也能夠調用其餘模塊的 action。

一樣的,當不一樣模塊中有同名 action 時,經過 store.dispatch 調用,會依次觸發全部同名 actions。

 

最後有一點要注意的是,將 store 中的 state 綁定到 Vue 組件中的 computed 計算屬性後,對 state 進行更改須要經過 mutation 或者 action,在 Vue 組件中直接進行賦值 (this.myState = 'ABC') 是不會生效的。

相關文章
相關標籤/搜索