Vuex 模块化和命名空间
- 在大型应用中,随着应用变得越来越复杂,我们需要管理越来越多的状态和数据。
- 多个模块之间的状态可能会相互依赖。
- 如果多个模块的字段名重复,容易造成很多错误。
为了解决上述问题,我们使用模块化+命名空间,将store对象分块,实现对不同模块管理。
1. 模块化
官方文档:
- 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
- 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。
举例:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import home from './home'
import search from './search'
export default new Vuex.Store({
// 实现Vuex仓库模块
modules:{
home,
search
}
});
const state = {
};
const mutations = {
};
const actions = {
};
const getters = {
};
export default {
// namespaced: true, // 是否开启命名空间
state,
mutations,
actions,
getters
}
2. 命名空间
官方文档:
- 默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对同一个 action 或 mutation 作出响应。
- 如果希望你的模块具有更高的封装度和复用性,你可以通过添加
namespaced: true的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
const store = createStore({
modules: {
account: {
namespaced: true,
// 模块内容(module assets)
state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
getters: {
isAdmin () { ... } // -> getters['account/isAdmin']
},
actions: {
login () { ... } // -> dispatch('account/login')
},
mutations: {
login () { ... } // -> commit('account/login')
},
// 嵌套模块
modules: {
// 继承父模块的命名空间
myPage: {
state: () => ({ ... }),
getters: {
profile () { ... } // -> getters['account/profile']
}
},
// 进一步嵌套命名空间
posts: {
namespaced: true,
state: () => ({ ... }),
getters: {
popular () { ... } // -> getters['account/posts/popular']
}
}
}
}
}
})
- 带命名空间的模块,具有更高的封装度和复用性
- 当模块被注册后,它的所有
getter、action及mutation都会自动根据模块注册的路径调整命名。
使用方法:
state:$store.state.模块名.属性名getter:$store.getters.['模块名/属性名']action:$store.dispatch('模块名/action名')mutation:$store.commit('模块名/mutation名')