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 才会执行。