Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、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 的状态 store.state.b // -> moduleB 的状态
修改 store\index.js
import Vue from 'vue' import Vuex from 'vuex' // 引入 Vuex 插件 Vue.use(Vuex) const home = { // 存放状态(共享属性) state: { count: 1 }, //派生属性 getters: { desc(state) { if(state.count < 50) { return '吃饭' }else if(state.count < 100) { return '睡觉' }else { return '打豆豆' } } }, // 改变 state 状态 mutations: { increment(state, n) { // n 为载荷 // state.count ++ state.count += n }, decrement(state) { state.count -- } }, actions: { add(context) { // 触发 mutations 中的 increment 改变 state context.commit('increment', 10) }, decrement({commit, state}) { // 按需传值 commit('decrement') } } } const store = new Vuex.Store({ // 注意V 和 S都是大写字母 modules: { home // home: home } }) export default store
修改 Home.vue
<template> <div> <!--修改部分--> count: {{ $store.state.home.count }} <button @click="addCount">加法</button> <button @click="decrement">减法</button> 派生属性desc: {{ $store.getters.desc }} </div> </template> <script> export default { methods: { addCount() { console.log(this.$store.state.home.count) this.$store.dispatch('add', 10) }, decrement(){ this.$store.dispatch('decrement') } }, } </script>
标准项目结构
如果所有的状态都写在一个 js 中,这个 js 必定会很臃肿,Vuex 并不限制你的代码结构。但是它建议你按以下代码
结构来构建项目结构:
├── index.html ├── main.js ├── api │ └── ... # 抽取出API请求 ├── components │ ├── App.vue │ └── ... └── store ├── index.js # 我们组装模块并导出 store 的地方 ├── actions.js # 根级别的 action ├── mutations.js # 根级别的 mutation └── modules ├── cart.js # 购物车模块 └── products.js # 产品模块
在 store下创建 modules 目录,该目录下创建 home.js
const state = { count: 1 } const getters ={ desc(state) { if(state.count < 50) { return '吃饭' }else if(state.count < 100) { return '睡觉' }else { return '打豆豆' } } } const mutations = { increment(state, n) { // n 为载荷 // state.count ++ state.count += n }, decrement(state) { state.count -- } } const actions = { add(context) { // 触发 mutations 中的 increment 改变 state context.commit('increment', 10) }, decrement({commit, state}) { // 按需传值 commit('decrement') } } export default { // 存放状态(共享属性) state, //派生属性 getters, // 改变 state 状态 mutations, actions }
修改 store\index.js, 导入 ./modules/home.js,删除之前的home变量
import Vue from 'vue' import Vuex from 'vuex' // 导入 Module import home from './modules/home' // 引入 Vuex 插件 Vue.use(Vuex) const store = new Vuex.Store({ // 注意V 和 S都是大写字母 modules: { home // home: home } }) export default store
正常访问, 与重构前一样