Modules
1. 前言
本節(jié)我們將介紹如何將 store 中的數(shù)據(jù)按模塊劃分。在復(fù)雜的大型項目中,如果將所有的數(shù)據(jù)都存在一個 state 對象中,那將使得 store 對象變得非常大,難于管理。這時候,使用 module 將變得異常重要。Modules 并非難點,接下來我們就一步步介紹 modules 的使用。
2. 如何使用
2.1 基本用法
Module 其實是一個對象,它和我們 new Vuex.Store ({…}) 傳入的對象格式相同。例如:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的狀態(tài)
store.state.b // -> moduleB 的狀態(tài)
2.2 模塊的局部狀態(tài)
對于模塊內(nèi)部的 mutation 和 getter,接收的第一個參數(shù)是模塊的局部狀態(tài)對象。
const moduleA = {
state: { count: 0 },
mutations: {
increment (state) {
// 這里的 `state` 對象是當(dāng)前模塊的局部狀態(tài)
state.count++
}
},
getters: {
doubleCount (state) {
// 這里的 `state` 對象是當(dāng)前模塊的局部狀態(tài)
return state.count * 2
}
}
}
同樣,對于模塊內(nèi)部的 action,局部狀態(tài)通過 context.state 暴露出來,根節(jié)點狀態(tài)則為 context.rootState:
const moduleA = {
// ...
actions: {
incrementIfOddOnRootSum ({ state, commit, rootState }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}
對于模塊內(nèi)部的 getter,根節(jié)點狀態(tài)會作為第三個參數(shù)暴露出來:
const moduleA = {
// ...
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count + rootState.count
}
}
}
完整示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div>模塊 A 數(shù)量:{{moduleACount}}</div>
<div>根節(jié)點 數(shù)量:{{rootCount}}</div>
<div>數(shù)量總和:{{countSum}}</div>
<button @click="addModuleCount">模塊 A + 1</button>
<button @click="addRootToModule">添加 root 至模塊</button>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.1.2/dist/vuex.js"></script>
<script type="text/javascript">
const moduleA = {
state: {
count: 18
},
getters: {
countSum(state, getters, rootState) {
return state.count + rootState.count
}
},
mutations: {
addModuleCount(state) {
state.count++
},
addModuleByCount(state, payload) {
state.count = state.count + payload.count
}
},
actions: {
addRootToModule({state, commit, rootState}) {
commit('addModuleByCount', {count: rootState.count})
}
}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
},
state: {
count: 20
}
})
var vm = new Vue({
el: '#app',
store,
computed: {
countSum() {
return this.$store.getters.countSum
},
moduleACount() {
return this.$store.state.a.count
},
rootCount() {
return this.$store.state.count
}
},
methods: {
addModuleCount() {
this.$store.commit('addModuleCount')
},
addRootToModule() {
this.$store.dispatch('addRootToModule')
}
}
})
</script>
</html>
代碼解釋
JS 代碼第 4-26 行,我們定義了模塊 moduleA。
JS 代碼第 9-11 行,在 moduleA 定義 getter countSum。
JS 代碼第 13-20 行,在 moduleA 定義 mutations。
JS 代碼第 21-25 行,在 moduleA 定義 actions。
JS 代碼第 27-34 行,我們定義了 store,并將 moduleA 傳入 modules 的屬性中。
3. 小結(jié)
本小節(jié)我們介紹了如何使用 Modules
進(jìn)行模塊化。主要有以下知識點:
- 如何定義一個模塊 module。
- 在 store 中利用 modules 屬性傳入定義的模塊 module。