专门在Vue中实现集中式状态(数据)管理的插件 (Vue.use(Vuex))
,对Vue应用中多个组件的共享状态进行集中式的管理(读、写),也是一种组件间通信的方式,且适用于任意组件间通信。
如果多个组件需要使用同一个数据的时候,可以利用Vuex
store管理action,mutations,state
store.dispatch(‘add’,2)
actions调用commit这个api,这时候流程走到mutations这里,mutations是一个对象,其中存储着add函数,add函数可以拿到state和数据2
mutations中的add函数中写state.sum+=2
,那么state中存储的sum就发生了改变。
之后vuex重新解析组件,进行渲染
vue2中要使用vuex3,vue3中要使用vuex4
npm i vuex@3
创建store文件夹==>创建index.js文件
index.js
//引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions对象,用于响应用户的动作
const actions={}
//准备mutations对象,用于修改state中的数据
const mutations={}
//准备store对象,用于存储用户数据
const store={}
//创建并暴露store对象
export default new Vue.Store({
actions,
mutations,
store
})
之后在main.js中import引入store并在创建vue实例对象的时候声明。
//在组件
methods:{
increment(){
//调用dispatch这个api通知action
this.$store.commit('ADD',this.n)
},
decrement(){
this.$store.commit('SUB',this.n)
},
oddIncrement(){
this.$store.dispatch('odd',this.n)
},
waitIncrement(){
this.$store.dispatch('wait',this.n)
}
}
//vuex
//准备actions对象,用于响应用户的动作
const actions={
// //dispatch通知到了action,这里进行操作
// add(context,value){
// //调用commit这个api通知mutations
// //context相当于一个miniStore,存储了dispatch和commit还有state等
// context.commit('ADD',value)
// },
// sub(context,value){
// context.commit('SUB',value)
// },
odd(context,value){
//上下文中存储着state
if(context.state.sum %2){
context.commit('ODD',value)
}
},
wait(context,value){
setTimeout(()=>{
context.commit('WAIT',value)
},500)
}
}
//准备mutations对象,用于修改state中的数据
const mutations={
ADD(state,value){
//对state中的数据进行操作
state.sum+=value
},
SUB(state,value){
state.sum-=value
},
ODD(state,value){
state.sum+=value
},
WAIT(state,value){
state.sum+=value
}
}
//准备state对象,用于存储用户数据
const state={
sum:0,
}
//创建并暴露store对象
export default new Vuex.Store({
actions,
mutations,
state
})
注意:
this.$store.commit('JIA',this.n)
getters可以将state中的数据进行加工,和计算属性的使用方法类似,都是通过return返回值来决定值
const getters={
mulSum(state){
return state.sum*10
}
}
export default new Vuex.Store({
actions,mutations,state,getters
})
在组件中使用: $store.getters.mulSun
如果模板中需要使用state中的数据,那么直接将this.$store.state.xxx
写在模板中会太长了(模板中最好不要写太长的语句),所以这里要用到计算属性
//使用
{{school}}
//计算属性
computed:{
add(){
return this.$store.state.sum
},
school(){
return this.$store.state.school
},
job(){
return this.$store.state.job
}
}
观察以上计算属性中的代码可以发现,这些代码前面相同,只有最后的后缀不同,所以这里可以通过Vuex中的mapState来实现以上计算属性中的代码
//导入mapState
import {mapState} from 'vuex'
export default{
computed:{
//es6中...可以将对象中的属性拆分出来
//借助mapState生成计算属性,从state中读取数据(对象写法)
...mapState({
add:'sum',
school:'school',
job:'job'
}),
//数组写法(生成的计算属性名和state中属性名要相同)
...mapState(['sum','school','job'])
}
}
用于映射getters中的数据为计算属性
import {mapGetters} from vuex
computed:{
//对象写法
...mapGetters({mulSum:'mulSum'})
//数组写法
...mapGetters(['mulSum'])
}
借助mapActions生成对应的方法,方法中会调用dispatch函数去联系actions
import {mapActions} from vuex
methods:{
oddIncrement(){
this.$store.dispatch('odd',this.n)
},
waitIncrement(){
this.$store.dispatch('wait',this.n)
}
//以下代码可以替代以上代码
//对象写法
...mapActions(oddIncrement:'odd',waitIncrement:'wait')
//数组写法
...mapActions('odd','wait')
@click='odd(n)'
}
借助mapMutations生成对应的方法,方法中会调用commit函数去联系mutations
import {mapMutations} from vuex
methods:{
// increment(){
// this.$store.commit('JIA',this.n)
// },
// decrement(){
// this.$store.commit('JIAN',this.n)
// }
//以下代码可以替代以上代码
//对象写法
...mapMutations({increment:'JIA',decrement:'JIAN'})
//数组写法
...mapMutions['JIA','JIAN']
@click= "JIA(n)"
}
要注意的是使用mapMutations
这个函数并没有传入参数,所以在绑定事件的时候要传入参数,原来的写法@click="increment"
,现在的写法是@click=increment(n)
将参数传入
目的是让代码更好维护,让多种数据分类更加明确
开启命名空间
const countAbout={
namespaced:true, //开启命名空间
state:{},
mutations:{},
actions:{},
getters:{}
}
const personAbout={
namespaced:true, //开启命名空间
state:{},
mutations:{},
actions:{},
getters:{}
}
const state=new Vuex.Store({
//这种方法声明命名空间
modules:{
countAbout,
personAbout
}
})
开启命名空间后,组件中读取state数据:
//自己直接读取
this.$store.personAbout.xxx
//借助mapState读取
...mapState('countAbout',['sum','school'])
开启命名空间后,组件中读取getters数据:
//自己直接读取
this.$store.getters['personAbout/xxx']
//借助mapGetters读取
...mapGetters('countAbout',['bigSum'])
开启命名空间后,组件中调用dispatch方法联系actions
//dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//mapActions
...mapActions('countAbout',{incrementOdd:'odd',incrementWait:'wait'})
开启命名空间后,组件中调用commit方法联系mutations
//commit
this.$store.commit('personAbout/add',person)
//mapMutations
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'})