应用结构
实际上,Vuex 在怎么组织你的代码结构上面没有任何限制,相反,它强制规定了一系列高级的原则:
1、应用级的状态集中放在 store 中。
2、改变状态的唯一方式是提交mutations,这是个同步的事务。
3、异步逻辑应该封装在action 中。
只要你遵循这些规则,怎么构建你的项目的结构就取决于你了。如果你的 store 文件非常大,仅仅拆分成 action、mutation 和 getter 多个文件即可。
对于稍微复杂点的应用,我们可能都需要用到模块。下面是一个简单的项目架构:
├── index.html
├── main.js
├── api
│ └── ... # 这里发起 API 请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 组合 modules 、export store
├── actions.js # 根 action
├── mutations.js # 根 mutations
└── modules
├── cart.js # cart 模块
└── products.js # products 模块
关于更多,查看 购物车实例。
Modules
由于使用了单一状态树,应用的所有状态都包含在一个大对象内。但是,随着我们应用规模的不断增长,这个Store变得非常臃肿。
为了解决这个问题,Vuex 允许我们把 store 分 module(模块)。每一个模块包含各自的状态、mutation、action 和 getter,甚至是嵌套模块, 如下就是它的组织方式:
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's statestore.state.b // -> moduleB's state
模块本地状态
模块的 mutations 和 getters方法第一个接收参数是模块的本地状态。
const moduleA = { state: { count: 0 }, mutations: { increment: (state) { // state 是模块本地的状态。 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } }}
相似地,在模块的 actions 中,context.state 暴露的是本地状态, context.rootState暴露的才是根状态。
const moduleA = { // ... actions: { incrementIfOdd ({ state, commit }) { if (state.count % 2 === 1) { commit('increment') } } }}
在模块的 getters 内,根状态也会作为第三个参数暴露。
新闻热点
疑难解答
图片精选