对vuex的理解及解析

  • Post author:
  • Post category:vue




vuex概述



官方定义:

Vuex 是一个专为 Vue.js 应用程序开发的

状态管理模式

。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具

devtools extension (opens new window)

,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。


vuex的优点

  • 能够在vuex中集中管理共享的数据,易于开发和后期维护;
  • 能够高效地实现组件之间的数据共享,提高开发效率;
  • 存储在vuex中的数据都是响应式的,能够实时保持数据与页面同步。


什么样的数据适合存储到Vuex中?

一般情况下,只有组件之间共享的数据,才有必要存储到Vuex中;对于组件中的私有数据,依旧存储在组件自身的data中即可。


vuex状态图



vuex安装及核心概念



安装方式

npm install vuex --save 

在一个模块化的打包系统中,您必须在入口函数main.js里显式地通过 Vue.use() 来安装 Vuex:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)


五个核心概念


State单一状态树




State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储;和vue中的data函数功能类似。


Mutations:

改变store中状态的唯一方式,第一个参数是state,第二个参数是传入的额外的参数或对象。Mutations函数

不能进行异步操作。


Action:

提交的是mutation,不能变更状态。Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象。Action 函数

可以处理异步操作


Getter:

就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。接受 state 作为其第一个参数,也可以接受其他 getter 作为第二个参数。


Module:

将 store 分割成

模块,

每个模块拥有自己的 state、mutation、action、getter

五种函数代码如下所示:

const store = new Vuex.Store({   //只创建一个store
    //五个核心概念
    state:{
   //这些属性都会被加入到响应式系统中,而响应式系统会监听属性的变化,当属性发生变化时,会通知所有页面
        count=10;   //用到该属性的地方,让界面发生刷新
       
    },
    mutations:{               //不能进行异步操作,且唯一变更状态方法
       add(state,payload){    //payload可以传额外的参数或对象
           
       },
    },
    actions:{  
       addAsync(context){   //可以进行异步操作
           setTimeout(()=>{     
                context.commit('add')   //action 提交的是 mutation中的add方法,而不是直接变更状态。       
           },1000)       
       }                             
    },
    getters:{
        //store中的数据经过改变
        showNum:state=>{
            return '当前最新的数量是['+state.count+']'        
        }
    },
    modules:{
        //抽离store,分割成模块,每个模块都有自己的store,actions,getters,mutations
        const moduleA = {           
          state: () => ({ ... }),
          mutations: { ... },
          actions: { ... },
          getters: { ... }
        }
    }
})


export  default store   //导出store独享



vuex在组件中的使用


首先在main.js文件中挂载store

import store from './store'

new Vue({
 store,
})}


在组件中调用的第一种方式

State:

this.$store.state.全局数据名称

Mutations:

this.$store.commit(‘方法名称’),

传参方式:

this.$store.commit(‘方法名’,{属性:值})

Actions:

this.$store.dispatch(‘异步函数名’)

传参方式:

this.store.dispatch(‘方法名’,{属性:值})

Getter:

this.$store.getters.名称


在组件中调用的第二种方式:辅助函数

State、Mutations、Actions、Getter的辅助函数分别是mapState、mapMutations、mapActions、mapGetter。

需要注意的是mapMutations和mapActions映射为当前组件的methods方法中,mapState和mapGetter需要映射为当前组件的computed计算属性中。

import { mapState,mapMutations,mapActions,mapGetters } from 'vuex'


methods:{
  ...mapMutations(['方法名1'],['方法名2'])
  ...mapActions(['方法名1'],['方法名2'])

}
computed:{
  ...mapState(['count'])    //'count'为当前组件需要的state中的全局数据
  ...mapGetters(['名称'])
}



写在最后



1.mutation中 为什么不能进行异步操作?

答:因为当 mutation 触发的时候,回调函数还没有被调用,devtools不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。


2.  Action 通常是异步的,那么 action 什么时候结束呢?

利用

async / await (opens new window)

,我们可以如下组合 action

// 假设 getData() 和 getOtherData() 返回的是 Promise

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

一个

store.dispatch

在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。



版权声明:本文为qq_41161982原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。