7-4 Element UI及Vuex-分模块组织Vuex
目录:
- 简介
- 组织vuex项目结构
- 具体示例
一、简介
之前我们把 state、actions、mutations等所有的东西,都是写在 store.js里面的,也就是说使用单一状态数,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变的相当臃肿。为了解决以上的文艺,Vuex允许我们将store分割成 模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割,官网解释:Module
二、组织Vuex项目结构
Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:项目结构
-
应用层级的状态应该集中到单个 store 对象中。
-
提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
-
异步逻辑都应该封装到 action 里面。
只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。
对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules # 根级别的是公共的,modules里面的是各个模块的,分为多个模块
├── cart.js # 购物车模块
└── products.js # 产品模块
请参考购物车示例,这些官方网站都有,只不过我在这边copy了一下,并且稍微加了一些补充。
三、具体示例
3.1、初始化项目
#初始化项目 >vue init webpack-simple vuex-demo2 .... #进入项目 >cd vuex-demo2 #安装依赖包 >npm install #安装vuex插件 > npm install vuex -S
3.2、项目目录结构
|-vue-demo2 //项目名
|-....
|-src
|-index.js
|-mutation-types.js //用来配置mutions的类型,我们定义为一个常量
|-getters.js
|-mutations.js //此次没有用到mutations,所以不做编辑
|-modules //分为多个模块,每个模块都可以拥有自己的state、getters、actions、mutations
|-user.js
|-...
|-.....
3.3、思路图

3.4、编辑main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store/index.js' //导入store对象
new Vue({
el: '#app',
render: h => h(App),
store //注册store
});
3.5、编辑modules-> user.js
/**
* 用户模块
*/
import types from '../mutations-types' //导入常量提交类型
//1.定义属性(数据)
let state={
count:6
};
//2.定义getters
let getters = {
count(state){ //参数state就是上面的state
return state.count;
}
};
//3.定义actions,要执行的操作,如流程判断,一部请求等
const actions = {
increment({commit,state}){ //es6的语法
commit(types.INCREMENT); //在常量中(mutation-type.js)定义突变的名字
},
decrement({commit,state}){
if(state.count>10){
commit(types.DECREMENT);
}
}
};
//4.定义mutations处理状态(数据)的改变
const mutations = {
[types.INCREMENT](state){ //我们可以通过使用ES6的语法[type.INCREMENT](state){},而不能直接使用type.INCREMENT(state){}的方式
state.count++;
},
[types.DECREMENT](state){
state.count--;
}
};
export default {
state,
getters,
actions,
mutations
};
3.6、编辑getters.js
/**
* 定义公共的getters,如果其他模块也想用的话,可以放在公用的getters.js中
*/
const getters = {
isEvenOrOdd(state){
return state.user.count%2 == 0?'偶数':'奇数'; //state.user区别是哪个模块的count变量
}
};
//别的js模块想用,必须先 导出
export default getters;
3.7、编辑 actions.js
/**
* 定义公共的actions,这个动作是公共的,根一级的actions
*/
import types from './mutations-types'
const actions = {
incrementAsync({commit,state}){
//异步操作
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve();
},3000);
});
p.then(()=> {
commit(types.INCREMENT); //这边我们通过调用mutation-types.js常量来提交
}).catch(() => {
console.log('异步操作');
});
}
};
export default actions;
3.8、 编辑mutation-types.js
说明:我们在提交的时候一般使用常量,所以这边我们专门定义一个模块来定义常量,=>使用常量替代 Mutation 事件类型
/**
* 定义类型常量
*/
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
export default {
INCREMENT,
DECREMENT
}
3.9、编辑index.js
/**
* 在index.js中要把所有的模块进行导出,是一个出口文件
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
import getters from './getters.js'
import actions from './actions.js'
import user from './modules/user.js'
export default new Vuex.Store({
getters,
actions,
modules:{ //模块的方式导入,因为Vuex.store没有user选项,只有module选项
user
}
})
3.10、编辑App.vue
<template>
<div id="app">
<button @click="increment">增加</button>
<button @click="decrement">减少</button>
<button @click="incrementAsync">增加</button>
<!--获取数据-->
<p>当前数据为:{{count}}</p>
<p>{{isEvenOrOdd}}</p>
</div>
</template>
<script>
import {mapGetters,mapActions} from 'vuex'
export default {
name: 'app',
//方式2:通过mapGetters、mapActions访问
computed:mapGetters([
'count', //对应的store.js中的getters中的count()方法
'isEvenOrOdd'
]),
methods:mapActions([
'increment',
'decrement',
'incrementAsync'
])
}
</script>
实现的效果:
当前数据为:14
偶数

浙公网安备 33010602011771号