1.简介
首先,你必须明显明白vuex到底是干啥的,主要解决开发中的哪些问题?
Vuex是一个专门为Vue.js应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式变化
说白了,就是:提供了那么一个公共存储的地方,存放各个组件的数据,组件访问数据和操作数据访问这个地方即可
所以,Vuex主要解决是组件间数据传递问题,尤其是嵌套组件,项目一大时,父子组件间的数据传递就非常麻烦了,而Vuex则提供了一种集中管理组件数据的方案,当然小型项目就没必要用Vuex了
2.Demo准备
- vue init webpack-simple vuex-demo
- cd vuex-demo
- npm install
- npm install vuex -S
3.访问store对象的两种方式
Vuex的核心是Store(仓库),相当于是一个容器,一个store实例中包含以下属性的方法:
- state 定义属性(状态、数据)
- getters 用来获取属性
- actions 定义方法(动作)
- commit 提交变化,修改数据的唯一方式就是显式的提交mutations
- mutations 定义变化
注:不能直接修改数据,必须显式提交变化,目的是为了追踪到状态的变化
创建store.js文件,在main.js中导入并配置store.选项
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//定义属性(数据)
var state = {
count: 6
}
//创建store对象
const store = new Vuex.Store({
state,
})
//导出store对象
export default store;
import Vue from 'vue'
import App from './App.vue'
import store from './store.js' //导入store对象
new Vue({
store,
el: '#app',
render: h => h(App)
})
方式一:通过this.$store访问
//方式1:通过this.$store访问
computed: {
count() {
return this.$store.state.count;
}
}
方式二:通过mapState、mapGetters、mapActions访问,vuex提供了两个方法
- mapState 获取state
- mapGetters 获取getters
- mapActions 获取actions
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//定义属性(数据)
var state = {
count: 6
}
//定义getters
var getters = {
count(state) {
return state.count;
}
}
//定义actions,要执行的操作,如流程判断、异步请求
const actions = {
increment(context) { //包含 commit dispatch state
context.commit('increment');
},
decrement(context) {
if (context.state.count > 10) {
context.commit('decrement');
}
}
}
//定义mutations,处理状态(数据)的改变
const mutations = {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
}
//创建store对象
const store = new Vuex.Store({
state,
getters,
actions,
mutations,
})
//导出store对象
export default store;
<template>
<div id="app">
<button @click="increment">增加</button>
<button @click="decrement">减小</button>
<p>当前数字为:{{count}}</p>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from "vuex";
export default {
name: "app",
data() {
return {
msg: "Welcome to Your Vue.js App"
};
},
//方式1:通过this.$store访问
/*computed: {
count() {
return this.$store.state.count;
}
}*/
/*computed:mapState([
'count'
])*/
computed: mapGetters(["count"]),
methods:mapActions([
'increment',
'decrement',
])
};
</script>
<style>
</style>
分模块组织Vuex
上面那种方式,所有的都写在一个文件,项目大时,难免看起来显乱,所以需要分模块来组织,原则上就私有和公共的分开进行组织
其中modules存放每个模块的,actions.js,getters.js,mutations.js存放公共的,目录如下

user.js
/**
* 用户模块
*/
import types from '../types.js'
const state={
count:6
}
var getters={
count(state){
return state.count;
}
}
const actions = {
increment({commit,state}){
commit(types.INCREMENT); //提交一个名为increment的变化,名称可自定义,可以认为是类型名
},
decrement({commit,state}){
if(state.count>10){
commit(types.DECREMENT);
}
}
}
const mutations={
[types.INCREMENT](state){
state.count++;
},
[types.DECREMENT](state){
state.count--;
}
}
export default {
state,
getters,
actions,
mutations
}
actions.js
import types from './types.js'
const actions={
incrementAsync({commit,state}){
//异步操作
var p=new Promise((resolve,reject) => {
setTimeout(() => {
resolve();
},3000);
});
p.then(() => {
commit(types.INCREMENT);
}).catch(() => {
console.log('异步操作');
});
}
}
export default actions;
getters.js
const getters={
isEvenOrOdd(state){
return state.user.count%2==0?'偶数':'奇数';
}
}
export default getters;
types.js
/**
* 定义类型常量
*/
const INCREMENT='INCREMENT'
const DECREMENT='DECREMENT'
export default {
INCREMENT,
DECREMENT
}
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:{
user
}
});
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store/index.js'
new Vue({
store,
el: '#app',
render: h => h(App)
})
分模块组织的访问
console.log(this.$store);
console.log(this.$store.getters['dirTestcaseData']);
console.log(this.$store.getters['user/count']);
console.log(this.$store.state['project']);
console.log(this.$store.state.user['count']);
this.$store.dispatch("asset/changeCurrentFundIndex", index);
this.$store.dispatch('increment');
//导入
import { mapState, mapGetters } from "vuex";
//批量引入
...mapGetters("asset", {
assetDetailType: "assetDetailType",
tradeSelectVal: "tradeSelectVal",
totalAsset: "totalAsset"
}) //也支持数组