Vuex - 在Vue.js中的集中状态管理 
注意
本文针对的是Vue 2。现在已经有了Vue 3,建议使用它来开发Vue应用程序。
在页面之间发送和接收数据的常见解决方案包括通过URL、cookies和LocalStorage传递数据。虽然这些方法可以工作,但它们没有提供操作数据的标准,也不是与Vue.js响应式相协调的响应式数据源。
Vue.js的创建者尤雨溪开发了一个名为Vuex的工具,专门为Vue设计,允许在使用该框架构建的Web应用程序中进行集中状态管理。虽然不是唯一的数据管理工具,但它与Vue生态系统集成得最好。
Vuex是一个用于Vue.js应用程序的状态管理模式库。它为应用程序中的所有组件提供了一个集中的存储,并有规则确保状态只能以可预测的方式进行变更。
对于需要跨不同组件访问集中、响应式数据的中大型应用程序,特别推荐使用Vuex。
安装 
通过CDN,将其放在vue之后:
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>使用NPM:
npm install vuex --save使用Yarn:
yarn add vuex在使用模块系统(如vue-cli中的webpack)时,需要通过Vue.use()显式安装Vuex:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);Vuex的基本结构 
const store = new Vuex.Store({
  state: {},
  mutations: {}, 
  actions: {},
  getters: {},
});state 
state是包含我们可以从不同组件访问的所有数据的对象。其内容应该只通过mutations进行修改,以使其修改透明且可审计。
state: {
  count: 0
}mutations 
在Vuex存储中更改状态的唯一方法是提交一个mutation。这些函数执行修改并接收state作为第一个参数。
mutations: {
  increment (state) {
    state.count++  
  }不能直接调用Mutations,所以它们通过store.commit执行:
store.commit('increment');Mutations也可以接收数据作为第二个参数,可以是数字、字符串、数组等。
mutations: {  
  increment (state, amount) {
    state.count += amount
  }
}store.commit('increment', 10);一个重要的点是mutations是同步的,这意味着任何状态更改都必须立即完成,而不能通过异步事务(如数据库或API查询)进行。对于异步状态更改,使用actions。
actions 
actions与mutations类似,除了两点不同:
- 它们通过store.dispatch分派
- actions不是直接变更状态,而是提交mutation
- actions可以包含异步代码
- 它们接收一个context对象作为第一个参数,该对象使我们能够访问state、mutations、actions和getters
- actions可以在resolved后返回一个promise
假设我们想在查询某个API后增加计数器,我们可以这样做:
actions: {
  asyncIncrement (context) {
    return new Promise((resolve, reject) => {
      fetch('someApiX').then(() => {
        context.commit('increment')
        resolve()
      }) 
    })
  }
}或使用async/await:
actions: {
  async asyncIncrement (context) {
    await fetch('someApiX')
    context.commit('increment') 
  }
}像这样使用:
store
  .dispatch('asyncIncrement')
  .then(() => console.log('计数器已增加!'));了解更多关于JavaScript Promises的信息。
getters 
getters用于从state中检索已处理的信息。它们接收state作为第一个参数。
假设我们在state中有一个任务列表,我们可以创建一个getter,只返回已完成的任务:
state: {
  tasks: [
    { id: 1, text: 'lorem ipsum', done: true },
    { id: 2, text: 'lorem ipsum', done: true },
    { id: 3, text: 'lorem ipsum', done: false },  
    { id: 4, text: 'lorem ipsum', done: false },
    { id: 5, text: 'lorem ipsum', done: true },
  ]
},
getters: {
  doneTasks (state) {
    return state.tasks.filter(task => task.done)
  }  
}像这样使用:
store.getters.doneTasks;
/*
[
  { id: 1, text: 'lorem ipsum', done: true }, 
  { id: 2, text: 'lorem ipsum', done: true },
  { id: 5, text: 'lorem ipsum', done: true },  
]
*/getters还可以通过返回一个函数来接收数据。因此,我们可以通过getter这样检索特定的任务id:
getters: {
  taskById: (state) => (id) => {
    return state.tasks.find(task => task.id === id)
  }
}像这样使用:
store.getters.taskById(2); // { id: 2, text: 'lorem ipsum', done: true }通过这种方式,我们可以管理组件中可访问的数据,这些数据可以通过mutations和actions进行变更,并且可以通过getters以处理后的形式进行查询。为我们的应用程序提供了一个标准的数据使用模式,使我们能够更快地进行扩展。

