1.概念
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
全局事件总线的方法去对其他组件的数据进行读和改,如图所示,十分繁琐
然而 vuex的方法相比起来就方便很多,如图所示
2.何时使用?
多个组件需要共享数据时
3.vuex流程
如图 求和案例中,Count 组件中有 jia 的方法和 加一个具体值2,
1.通过dispatch(‘jia’, 2)给到Actions中, Actions是一个对象(用于响应组件中的动作
),key-value的形式存放传过来 jia 和 function函数。Actions这里一般做一些业务逻辑,比如发送一个ajax等。
2.然后通过commit(‘jia’, 2)传递给Mutations中,Mutations同样也是一个对象(用于操作数据(state
))
若知道具体加多少值的话,就直接commit给Mutations
这3个东西由store来领导
4.vuex的搭建
求和案例为例子,如下图所示, 使用vuex来写
这里要注意一点,我使用的是vue2,所用要使用个vuex的3版本,如果直接下载,会默认下载vuex的4版本
1.创建文件: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
})
2.在main.js
中创建vm时传入store
配置项
......
//引入store
import store from './store'
......
//创建vm
new Vue({
el:'#app',
render: h => h(App),
store
})
实例代码
运行结果: vm和vc(组件实例)上都出现了$store
求和案例vuex代码 如下所示
如果知道相加的具体值,可以在count组件中直接使用commit,不需要dispatch了
注意一:
jiaOdd(context, value) {
console.log('jiaOdd被调用', context);
if (context.state.sum % 2 != 0) {
context.commit('JIAODD', value)
}
},
context为:
注意二:context中的dispatch
注意三
5.getters的使用
-
概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
-
在
index.js
中追加getters
配置
......
const getters = {
bigSum(state){
return state.sum * 10
}
}
//创建并暴露store
export default new Vuex.Store({
......
getters
})
- 组件中读取数据:
$store.getters.bigSum
实例代码
6.四个map方法的使用
场景,如何简写computed中的写法呢,使其插值语法显的也不长
解决:
- mapState方法:用于帮助我们映射
state
中的数据为计算属性
computed: {
//借助mapState生成计算属性:sum、school、subject(对象写法)
...mapState({sum:'sum',school:'school',subject:'subject'}),
//借助mapState生成计算属性:sum、school、subject(数组写法)
...mapState(['sum','school','subject']),
},
- mapGetters方法:用于帮助我们映射
getters
中的数据为计算属性
computed: {
//借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'}),
//借助mapGetters生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
},
场景:想要在methods直接与mutations和actions对话
与mutations对话
会报错:因为increment并没有传参数,默认传event, 当进行点击事件的时候就会发生错误
修改
与actions对话
- mapActions方法:用于帮助我们生成与
actions
对话的方法,即:包含$store.dispatch(xxx)
的函数
methods:{
//靠mapActions生成:incrementOdd、incrementWait(对象形式)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//靠mapActions生成:incrementOdd、incrementWait(数组形式)
...mapActions(['jiaOdd','jiaWait'])
}
- mapMutations方法:用于帮助我们生成与
mutations
对话的方法,即:包含$store.commit(xxx)
的函数
methods:{
//靠mapActions生成:increment、decrement(对象形式)
...mapMutations({increment:'JIA',decrement:'JIAN'}),
//靠mapMutations生成:JIA、JIAN(对象形式)
...mapMutations(['JIA','JIAN']),
}
备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。
7.多组件共享数据
运行结果
8.模块化+命名空间
-
目的:让代码更好维护,让多种数据分类更加明确。
-
修改
index.js
const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations: { ... },
actions: { ... },
getters: {
bigSum(state){
return state.sum * 10
}
}
}
const personAbout = {
namespaced:true,//开启命名空间
state:{ ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
countAbout,
personAbout
}
})
- 开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),
- 开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])
- 开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
- 开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
具体实例代码
index.js
Count.vue