Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。在学习 Vue.js 时,大家一定知道在 Vue 中各个组件之间传值的痛苦,在 Vue 中我们可 以使用 Vuex 来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新。
 Vuex 是适用于在 Vue 项目开发时使用的状态管理工具。试想一下,如果在一个项目开 发中频繁的使用组件传参的方式来同步 data 中的值,一旦项目变得很庞大,管理和维护这 些值将是相当棘手的工作。
 状态管理:简单理解就是统一管理和维护各个 vue 组件的可变化状态(你可以理解成 Vue 组件里的某些 data )。 
      
让我们从一个简单的 Vue 计数应用开始,代码如下:
//src/components/count.vue 
<template> 
            <div>
            <!-- view --> 
            <div>{{ count }}</div> 
            button @click="increment">increment</button> 
</div> 
</template> 
<script> 
export default { 
            // state 
            data () { 
            return { 
            count: 0 
       } 
},
      // actions 
        methods: { 
            increment () { 
                      this.count++ 
            } 
}}
</script>
这个状态管理应用包含以下几个部分:
State:驱动应用的数据源,通常用在 data。 
View:以声明方式将 state 映射到视图,通常用在 template。  
Actions:响应在 view 上的用户输入导致的状态变化,即通过方法对数据进
行操作, 通常用 methods。

 

 

      这里的数据 count 和方法 increment 只有在 count.vue 组件里可以访问和使用,其他的组 件是无法读取和修改 count 的。但是,当我们的应用遇到多个组件共享状态时,单向数据流 的简洁性很容易被破坏。

     因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

这就是 Vuex 背后的基本思想,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新

 

 

注意:使用Vuex会有一定的门槛和复杂性,它的主要使用场景是大型单页应用,更适合多人协同开发
1.安装 首先通过 NPM 安装 Vuex 依赖,命令如下:

npm install vuex --save
2.使用 
(1)在项目根目录创建 store 文件夹,在该文件夹下创建 index.js,代码如下:
import Vue from 'vue'           //store/index.js 
import Vuex from 'vuex' 
//挂载 
Vuex Vue.use(Vuex) 
//创建 VueX 对象
const store = new Vuex.Store({
              state:{
                        //存放的键值对就是所要管理的状态
            name:'这是 Vuex 的第一个数据' 
}}) 
//导出 
store export default store
(2)在 main.js 文件中将 store 挂载到当前项目的 Vue 实例中去,代码如下:
//main.js 部分代码省略 
import store from './store'//导入 store,自动会寻找 index.js 
new Vue({ 
   el: '#app', 
   router, 
   store, //store:store 和 router 一样,将我们创建的 Vuex 实例挂载到这个 vue 实例中   
   components: { App }, 
   template: '<App/>' 
})
(3)在组件中使用 Vuex,如在 HelloWorld.vue 中,我们要将 state 中定义的 name 拿来 在 h1 标签中显示,代码如下:
<template> 
     <div id="hello"> 
           name: 
           <h1>{{ $store.state.name }}</h1><!--获取 state 中的值--> 
    </div> 
</template>
     在 VueX 对象中,其实不止有 state,还有用来操作 state 中数据的方法集,以及当我们 需要对 state 中的数据需要加工的方法集等成员。成员列表如下:
State:数据源存放状态。 
mutations state:成员操作。
Getters:加工 state 成员给外界。
Actions:异步操作。 
Modules:模块化状态管理。
(1)Mutations:mutations 是操作 state 数据的方法的集合,比如对该数据的修改、增 加、删除等。
mutations 方法有默认的形参([state] [,payload]):
state 是当前 VueX 对象中的 state 。 
payload 是该方法在被调用时传递参数使用的。
例如编写一个方法,当被执行时,把 state 中管理的 name 值修改成“beixi”,代码如下:
//store/index.js 部分代码省略
const store = new Vuex.Store({ 
    state:{
       name:'helloVueX'//存放的键值对就是所要管理的状态 
    },
    mutations:{ 
      edit(state){//es6 语法,等同 edit:funcion(){...} 
              state.name = 'beixi' 
           } 
      } 
})
而在组件中,我们需要去调用 mutation,例如在 HelloWorld.vue 的任意方法中调用,代码如下:
//HelloWorld.vue 部分代码省略 
<button @click="edit">获取修改后数据</button> 
export default { 
   methods: { 
     edit(){ 
            this.$store.commit('edit')
       } 
}}
(2)Mutation 传值:在实际生产过程中,需要在提交某个 mutation 时携带一些参数给方法使用。
单个值提交时,代码如下:
this.$store.commit('edit',18)
当需要多参提交时,推荐把他们放在一个对象中来提交,代码如下:
this.$store.commit('edit',{age:18,sex:'男'})
在 HelloWorld.vue 页面方法中接收挂载的参数,代码如下:
edit(state,payload){ 
          state.name = 'beixi' 
          console.log(payload) // 18 或{age:18,sex:'男'} 
}
(3)增删 state 中的成员
      为了配合 Vue 的响应式数据,我们在 Mutations 的方法中,应当使用 Vue 提供的方法来 进行操作。如果使用 delete 或者 xx.xx = xx 的形式去删或增,则 Vue 不能对数据进行实时响应。
Vue.set 为某个对象成员设置值,若不存在则新增。例如对 state 对象中添加一个 age 成员,
代码如下:
Vue.set(state,"age",18)
Vue.delete 删除成员,将刚刚添加的 age 成员删除,代码如下:
Vue.delete(state,'age')
(4)Getters:相当于 Vue 中的 computed 计算属性,getter 的返回值会根据它的依赖被 缓存起来,且只有当它的依赖值发生了改变才会被重新计算,这里我们可以通过定义 Vuex 的 Getter 来获取,Getters 可以用于监听、state 中的值的变化,返回计算后的结果。
Getters 中的方法有两个默认参数:
state 当前 VueX 对象中的状态对象。  
getters 当前 getters 对象,用于将 getters 下的其他 getter 拿来用,如下面代码所示:
//store/index.js 部分代码省略 
const store = new Vuex.Store({ 
        //... 
        getters:{ 
        nameInfo(state){ 
      return "姓名:"+state.name 
     },
       fullInfo(state,getters){ 
        return getters.nameInfo+' 年龄:'+state.age 
        } 
    } 
})
HelloWorld.vue 组件中调用,代码如下:
<div id="hello"> 
           <h3>从 Getters 获取计算后的值:{{this.$store.getters.fullInfo}}</h3> 
</div>
(5)Actions:由于直接在 mutation 方法中进行异步操作,将会引起数据失效。所以提 供了 Actions 来专门进行异步操作,最终提交 mutation 方法。
Actions 中的方法有两个默认参数:
context 上下文(相当于箭头函数中的 this)对象。  
payload 挂载参数。
例如我们在两秒后执行 mutations 中的 edit 方法,由于 setTimeout 是异步操作,所以需 要使用 actions,代码如下:
//store/index.js 部分代码省略 
const store = new Vuex.Store({ 
//... 
   actions:{ 
      aEdit(context,payload){ 
        setTimeout(()=>{ 
                 context.commit('edit',payload) 
             },2000) 
        } 
   } 
})
  在 HelloWorld.vue 组件中调用,代码如下:  
//HelloWorld.vue 部分代码省略 
<button @click="aEdit">异步获取数据</button> 
export default { 
   methods: { 
      aEdit(){ 
            this.$store.dispatch('aEdit',{age:18}) 
        } 
   }}
      对上述代码进行改进,由于是异步操作,所以我们可以为我们的异步操作封装为一个 Promise 对象,代码如下:
aEdit(context,payload){ 
    return new Promise((resolve,reject)=>{ 
        setTimeout(()=>{ 
                context.commit('edit',payload) 
                resolve() 
               },2000) 
        }) 
    }