Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采取集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。每一个Vuex应用的核心是store,它包含中应用中的大部分状态(state)。Vuex和全局对象有以下两点不同:
1,Vuex中的状态存储是响应式的。当vue组件从store中读取状态的时候,若store中的状态发生变化的时候,那么相应的组件也会得到更新
2,改变store中的状态唯一方法就是显性的提交(commit)mutation。
几个核心概念:
State
如何在vue组件中展示状态?由于Vuex的存储状态是响应式的,最简单的方法就是在计算属性中返回某个状态:

const Counter = {
  template : `<div>{{count}}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}
每当store.state.count变化的时候,都会重新求取计算属性,并且触发相关联的DOM

Getter
Vuex允许我们在store中定义'getter'(可以认为是store的计算属性),就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖发生了变化才会被重新计算。

const store = new Vuex.Store({
  state : {
    todo: [
      {id:1,text: '...',done: true},
      {id:2,text: '...',done: false}
    ]
  },
  getters: {
    doneTodos: (state)=> {
      return store.state.todo.filter(todo = > todo.done)
    }
  }
})

Getter会暴露为store.getters对象:

store.getters.doneTodos // 返回。 [{id:1,text: '...',done: true}] 

mapGetters 辅助函数
mapGetters 辅助函数仅仅是将store中的getter映射到局部计算属性

import {mapGetters} from 'vuex'
export default {
  computed: {
    ...mapGetters(['doneTodos'])
  }
}
如果想将其中的一个getter改变为另外一个名字,则使用对象形式
export default {
  computed: {
    ...mapGetters({
      donetode: 'doneTodos'
    })
  }
}

Mutation
更改Vuex的store中状态的唯一方法是提交mutation,Vuex中的mutation非常类似于事件,每一个mutation都有一个字符串的事件类型(type)和一个回调函数,这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数,需要注意一点的是mutation里面全部都是同步操作
对象风格的提交方式
提交mutation的另一种方式是直接使用包含type属性的对象:
使用常量替代mutation事件类型是很常见的的模式

//mutation-type.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import {SOME_MUTATION} from './mutation-type.js'
const store = new Vuex.Store({
  state: {....}
  mutations: {
    [SOME_MUTATION] (state,payload) { // 可以使用es2015风格使用一个常量作为属性名
      ...                             // 常规操作
    }
  }
})
// vue组件中的使用
方法一:
import {SOME_MUTATION} from './mutation-type.js'
// 需要存值的地方
this.$store.commit(SOME_MUTATION,{})
方法二:
使用辅助函数mapMutations将组件中的methods映射为store.commit调用
import {mapMutation} from 'vuex'
export default {  methods: {
    this.someMutation({}) // 需要存值的地方
    ...mapMutations({
      someMutation: 'SOME_MUTATION' // 将this.someMutation()映射为this.$store.commit(SOME_MUTATION,{})
    })
  }
}

Action
Action类似于mutation,但是Action是用来提交mutation的,不是来提交状态的改变的,并且Action可以包含任何异步操作

const store = new Vuex.Store({
  state:{
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
    context.commit('increment')
    }
  }
})
ES6中简写actions
actions: {
  increment ({commit}) {
    commit('increment')
  }
}

Action函数接受一个与store实例具有相同方法和属性的context对象,因此可以通过context.commit(),提交一个mutation,还可以通过context.state和context.getters来获取state和getter

分发Action
this.$store.dispatch()

Module
由于使用单一的状态树,应用的所有的状态都会集中到一个比较大的对象,当应用变得非常复杂时,store对象就可能变得非常臃肿,为了解决以上问题,Vuex允许可以将store分割成模块儿(module),每个模块儿都拥有自己的state,getter,mutation,action
具体例子如下:

const moduleA = {
  state: {...},
  mutations:{...},
  getters: {...},
  actions: {...}
}
const moduleB = {
  state: {...},
  mutations: {...},
  getters: {...},
  actions: {...}
}
const store = new Vuex.Store({
  modules:{
    a:moduleA,
    b:moduleB
  }
})

可以通过store.state.a //访问到moduleA的状态

store.state.b // 访问到moduleB的状态

这个module依据项目的大小以及人员配合而定,不一定都得使用