是什么?
vuex是专门为vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可以预测的方式发生变化。
———–引自vuex官网
我的理解:vuex是为了保存组件之间共享数据而诞生的,如果组件之间有需要共享的数据,可以直接挂载到vuex中,而不必通过组件之间父子传值。vuex就是一个全局共享数据存储区域,相当于是一个数据的仓库
结构
一般情况下使用vue-cli创建的项目的vuex是定义在项目src目录下的store.js
的文件里的,下面是一个典型的store.js
文件的结构:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
export default new Vue.Store({
state:{
count:0
}//全局共享数据存放区,以count为例
mutaitions:{
//mutations里面定义的方法的第一个参数默认是state。第二个参数可以是从外界调取该方法传入的参数
add(state,args){
state.count +=1
}
}//更改 Vuex 的 store 中的状态的方法区
actions:{
//定义在actions里面的方法都默认接受一个context参数,这个context是一个和store实例具有相同属性和方法的对象
async myadd(context){
context.commit('add')//在这些函数里面就这样调用mutations里面的方法
let result = await axios.get('xxx')
return `当前count是${context.state.count}>>>>>>>${result}`
}
}//类似于mutation,但是可以有一些异步操作方法在里面。配合async/await食用更佳
getters:{
//getters属性存储的方法默认接受一个参数为state,这些方法只能只读性的去访问state里面的属性,每一个定义在getters方法一般都会return一个东西
getCount(state){
return `count:${state.count}`
}
}//对state中存放的变量的只读性操作的方法存放区
modules:{}//
})
state
这个属性里存放着组件间需要共享的数据,如果在某个组中想要访问state里面的count
,只能通过this.$store.state.count
来访问。
在实际操作中,可以使用mapState来简化访问操作,具体而言就是在组件的computed属性中使用mapState
import {mapState} from 'vuex'
export default {
computed:{
...mapState(['count'])//数组中的元素就是你在这个组件中想要访问的state上的数据的名字
}
}
//通过这样的操作,再在组件中访问这个属性的时候,原来的方法是{{ $store.state.count}},现在是{{count}}
mutations
如果想要改变state里面存储的变量的状态,只能使用在mutations定义的方法来操作对应的属性,不推荐直接操作state里面的数据,因为万一导致了数据的紊乱,不能快速定位到错误的原因,因为每个组件中都可能有操作数据的方法。
如果在组件中想调用定义在mutations里面的方法,原始的途径是通过this.$store.commit('add',args)
。在实际操作中,可以使用mapMutations来简化操作,具体而言就是在组件methods方法中使用mapMutations
import {mapMutations} from 'vuex'
export default {
methods:{
myAdd(){
this.add(args)//this.$store.commit('add',agrs)
}
...mapMutations(['add'])
}
}
getters
这个属性中的方法类似于计算属性,当state里面的相关数据改变的时候,就会调用这个方法。在实际操作中使用mapGetters来方便我们操作,具体而言就是在组件的computed属性中使用mapGetters
import {mapGetters} from 'vuex'
export default {
computed:{
...mapGetters(['getCount'])//
}
}
原始的使用方式是{{$store.getters.getCount}},在使用完mapGetters之后
在组件中就可以通过{{getCount}}来调用这个方法。当state里面的count属性值变化的时候,就会调用getCount方法,从而更新视图。
actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态
- Action 可以包含任意异步操作。
在组件间使用的actions里面的方法时,最原始的方法是通过this.$store.dispatch()
,通过使用mapActions可以简化这个操作,具体而言,就是在组件的methods属性中使用mapActions
import {mapActions} from 'vuex'
export default {
methods:{
async myAdd(){
var result = await this.myadd()//this.$store.dispatch('myadd')
console.log(result)
}
...mapActions(['myadd'])
}
}
module
这个属性只是为了对存储在state里面的数据做模块性分隔,假设此时我们有两个store对象,一个是app,一个是user,里面的内容分别是
const app = new Vuex.store({
state:{
count:0
},
mutations:{
add(state){
state.count++;
}
},
getters:{
dec(state){
return `current count is{state.count}`
}
},
actions:{}
})
export default app
const user = new Vuex.Store({
state:{
userInfo:null
}
})
export default user
而在store.js里面就是
import app from 'app.js'
import user from 'user.js'
import Vue from 'vue'
import Vuex from 'vuex'
export default new Vue.Store({
state:{
app,user
}
})
这样就完成了状态的模块划分。这样之后,需要在组件中稍加修改
import {mapState,mapMutations,mapGetters}
export default {
computed:{
...mapState([{
count(state){
return state.app.count//原来没模块划分的时直接是...mapState(['count]),划分之后要做一层映射,这样就可以以{{count}}的形式来访问app里的state里面state存储的count属性了
}
}])
}
}