1.Vuex
Vuex是在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
为什么有了消息订阅与发布还要vuex?
因为如果多个组件需要共享同一个数据同一个对象的话,使用消息订阅与发布会使得代码冗长且不方便,这个时候就可以使用vuex,vuex像git,我们把东西上传上去其他人都能使用,其他人修改的话也会上传到git上;
Vuex的工作原理图解析
使用vuex之后,只要在vc或者vm中use了vuex,他们的身上就会多一个$store的配置项,我们配置好vuex的store之后,就可以使用this.$store.dispatch等方法了;
vuex的工作流程就是vc通过dispatch('事件名',传入参数)来告诉Actions应该告知Mutation什么事件和传递什么参数,Actions处可以调用ajax请求或者其他的后端api获得数据,如果没有这个业务逻辑的话dispatch这一步可以跳过直接调用commit。随后Mutation通过调用方法使得state中的共享数据得到改变,渲染到vc上。
如何搭建vuex环境
先安装vuex,vue2只能安装vuex3,vue3只能安装vuex4,现在默认安装的是vuex4,如果需要vuex3需要手动指定版本号(npm i vuex@3)
在src下创建store目录,其中新建index.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
在main.js中创建vm时候传入store配置项
如何使用Vuex
在组件中:
- this.$store.dispatch('funName',param)
在store下的js中:
- actions中:这里的context相当于一个ministore,他有store的一些方法
funName(context,param){ context.commit('funName',param); }
-
mutations中:这里可以拿到state
funName(state,params){ //这个函数里面写对stata数据的操作还有逻辑 }
组件中拿共享数据:
- this.$store.state
总而言之,commit是和mutations对话,dispatch是和actions对话;
commit可以在actions和store中调用;
2.getters配置项
当需要对state的数据进行加工再使用时,就可以使用getters
如何使用?
在store的js中加入:
const getters = {
bigSum(state){
return state.sum *10
}
}
随后就可以通过$store.getters.bigSum获得数据了。
3.四个map
3.1 mapState和mapGetters
mapState可以帮助我们拿state中的数据在computed中计算属性;
mapGetters可以帮助我们拿getters中的数据在computed中计算属性
...是扩展运算符,表示把mapState对象中的数据拆开然后放到computed对象中;
[‘sum’,‘school’,‘subject’]的详细写法是[sum:'sum',........],加单引号是因为我们找的并不是sum这个变量,而是指示vuex去countAbout中的state帮我们找sum;
3.2 mapMutations和mapActions
mapMutations和mapActions可以帮我们拿state中的数据在methods中定义方法;
🔺扩展知识点:
- vue的事件绑定如果不传入参数的话,默认传入的是event参数;例如@click=‘plus’传入的是鼠标事件这个参数;如果有传入参数的话则event参数消失。
mapActions同理;
4.Vuex的模块化编码
为了方便后续代码的维护和可读性,需要对vuex进行模块化编码;
不同的业务放在不同的js中,每一个js中都包含actions、mutations、state、getters,同时最重要的是namespaced:true
//求和相关的配置
export default {
namespaced:true,
actions:{
jiaOdd(context,value){
console.log('actions中的jiaOdd被调用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被调用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
},
mutations:{
JIA(state,value){
console.log('mutations中的JIA被调用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被调用了')
state.sum -= value
},
},
state:{
sum:0, //当前的和
school:'尚硅谷',
subject:'前端',
},
getters:{
bigSum(state){
return state.sum*10
}
},
}
模块都写好之后,在index引用即可
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//应用Vuex插件
Vue.use(Vuex)
//创建并暴露store
export default new Vuex.Store({
modules:{
countAbout:countOptions,
personAbout:personOptions
}
})
之后在使用时,countAbout和personAbout就是他们的名称;
不同于非模块化的写法,在调用mapState等方法时需要指定模块名称才能找到对应配置: