【Vue】vuex的getters mapState mapGetters mapMutations mapActions的使用
目录
一、getters
二、 mapState
三、 mapGetters
四、 mapMutations
五、 mapActions
学到这儿来个小总结:四个map方法的使用
总结不易~ 本章节对我有很大的收获, 希望对你也是!!!
本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/25_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_getters
通过前面介绍的vuex功能还是十分强大,但是对于模板中有很多不同需求的话,我们就不要自己来写js表达式了,当功能过于复杂,我们就要封装一个容器来进行存储这个功能
就比如模板要将当前求和放大10倍
<h1>当前求和为:{{ $store.state.sum }}</h1><h3>放大10倍的和:{{ $store.state.sum * 10 }}</h3>
这里功能开始变得复杂,那么就可以考虑是不是可以封装到计算属性里面呢?computed
<h3>放大10倍的和:{{ dahe()}}</h3>computed: {dahe() {return this.$store.state.sum * 10}},
但是这里就有一个问题,这个方法就只能自己组件里面使用,不能让组件之间进行共享,所以这里就引入了新的vuex配置项,getters
一、getters
// 准备getters——用于将state里面的数据进行加工
const getters = {bigSum(state) {return state.sum * 10}
}// 创建 并 暴露store
export default new Vuex.Store({actions,mutations,state,getters
})
在vuex里面进行创建getters,然后实现你要完成的方法,并且将getters引入store中
那么怎么引入getters的数据到模板中呢?
我将sum修改成1好进行观察
// 准备state——用于存储数据
const state = {sum: 1
}
利用生命周期挂载输出MyCount里面的$store
能够看到我们实现的bigSum函数值为10,那么获取就可以直接在模板中访问我们想要得到的值
<h3>放大10倍的和:{{ $store.getters.bigSum }}</h3>
所以getters就是拿着数据源里面的数据进行加工然后再给你返回加工后的值。由此,state像极了data,而getters像极了computed计算属性
回到MyCounst组件中, 我们发现一遍遍的书写$store.state.……实在是过于麻烦,我们的终极目标就是只写sum、bigSum、school、subject
那有一种办法就是利用计算属性,可以实现:这样就解释了sum并不是函数名,而是一个计算属性
<h1>当前求和为:{{ sum }}</h1><h3>放大10倍的和:{{ bigSum }}</h3><h3>我在{{ school }},学习{{ subject }}</h3>computed: {sum: function asdhaksdjaslkdjasdkalskdl() {return this.$store.state.sum},school() {return this.$store.state.school},subject() {return this.$store.state.subject},bigSum() {return this.$store.getters.bigSum},},
但是!不出意外的话就要出意外了!你不觉得这些计算属性里面的函数值都很类似吗? 也同样是return this.$store.state……,有没有什么方法可以直接写一个test函数,然后生成return this.$store.state这么一段,让我们直接进行调用呢!!
有的兄弟有的!Vue的设计者也想到了这一点,就给我们设计好了mapState
本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/26_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_mapState%E5%92%8CmapGetters
二、 mapState
import { mapState } from 'vuex'
我修改掉函数名, 只是想证明函数名跟配对的属性值是一组,好让mapState工作的时候进行映射能看看清楚是同一组数据在进行映射
mounted() {const x = mapState({'he':'sum'})console.log(x)}
由于mapState是要求传入的对象,那么就是key-value进行配对,那么key值永远都是一个字符串,可以用简写形式, 但是value却不行,如果value就写成sum, 他就会去寻找sum这个变量,但是我们的sum是一个属性名啊,也是一个字符串,所以sum要加上引号,让他是一个字符串
mounted() {const x = mapState({he:'sum', xuexiao:'school', xueke:'subject'})console.log(x)}
但是这里引入mapState确保错了!这里就要考es6的基本功怎么样了
由于对象里面是不能直接写对象的,否则就会报错
那么我们要是有个obj2也是对象,怎么添加到obj里面呢?
let obj2 = { x: 100, y: 200 }let obj = {a: 1,b: 2,...obj2}
写成...obj2就不会报错了,这样就是默认将obj里面的元素合并到obj里面!
所以, 你看清楚mapState在控制台中是一个对象!而computed计算属性也是一个对象,就不能直接放在computed里面 而是要加...mapState才是能够将当前的mapState对象里面的值合并到computed里面!
computed: {// 借助mapState生成计算属性, 从state中读取数据 (对象写法)...mapState({he:'sum', xuexiao:'school', xueke:'subject'})},
此时的computed计算属性里面就相当于,我写了那么多一长串的代码,页面仍然更新正常,怎么是不是超级方便!
唯一的不一样就是用mapState生成出来的计算属性,又单独在开发者工具里面多开一行,是隶属于计算属性的一栏,告诉开发者是你利用mapState来生成的一堆绑定数据
这里就先回到最初的命名规则
...mapState({sum:'sum', school:'school', subject:'subject'}),
那么就一定有人说,啊呀!可以用es6简写办法!
...mapState({sum, school:'school', subject:'subject'}),
现在可以看到,当前的sum就会被Vue解析成sum: sum, 仍然会遇到上面那个问题,变成key-value值,上面的sum会被解析成'sum' 但是后面那个sum会被去寻找sum变量,找不到而报错
那么另一种数组写法,就是采用mapState映射的关系告诉Vue,你这个计算属性的名字是叫'sum',是从'sum'这个 state的sum属性中来得到的数据,所以这里的命名就必须要跟state的属性名字一模一样,不能在跟上面he作为计算属性!!!
computed: {// 数组写法...mapState(['sum', 'school', 'subject']),},
三、 mapGetters
所以下面还有一个从getters里面取到的值也是一样的获取效果
import { mapState, mapGetters } from 'vuex'// 对象写法...mapGetters({bigSum:'bigSum'})//数组写法...mapGetters(['bigSum'])
yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/27_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_mapMutations%E5%92%8CmapActions 本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.com
https://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/27_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_mapMutations%E5%92%8CmapActions
四、 mapMutations
学懂了上面的计算属性,后面还有两个就好理解了!对于commit提交事件也是这么写,进行引入mapMutations
import { mapState, mapGetters, mapMutations } from 'vuex' methods: {// increment() {// this.$store.commit('JIA', this.n)// },// decrement() {// this.$store.commit('JIAN', this.n)// },...mapMutations({increment:'JIA', decrement:'JIAN'}),
但是当我点击+ 却报错了,而'JIA'却别调用了!
回到vuex里面观察是不是传入值value错误了
// 准备mutations——用于操作数据(state)
const mutations = {JIA(state, value) {console.log(value)console.log('mutations被调用了')state.sum += value},JIAN(state, value) {state.sum -= value}
}
是一个鼠标点击事件,说明就是value传值错误!
原因就是,原本我们自己写的increment函数里面是自己带this.n的参数进行传入mutations来进行接收,但是我们用mapMutations写后,就没有传入参数给他接收,那么就是默认参数event被传入
那么只要我们在模板里面调用函数的时候传参就欧克啦~
<button @click="increment(n)">+</button><button @click="decrement(n)">-</button>data() {return {n:1, // 用户当前选择的数字}},methods: {// increment() {// this.$store.commit('JIA', this.n)// },// decrement() {// this.$store.commit('JIAN', this.n)// },// 借助mapMutations生成对应的方法, 方法中会调用commit去联系mutations// 对象的写法...mapMutations({increment:'JIA', decrement:'JIAN'}),},
数组写法
// 数组的写法...mapMutations(['JIA', 'JIAN']),// 同样 模板里面的调用方法得改<button @click="JIA(n)">+</button><button @click="JIAN(n)">-</button>
这里要与vuex里面的mutations里面实现的方法一致
// 准备mutations——用于操作数据(state)
const mutations = {JIA(state, value) {console.log('mutations被调用了')state.sum += value},JIAN(state, value) {state.sum -= value}
}
五、 mapActions
还有最后一步,引入mapActions
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'// incrementOdd() {// this.$store.dispatch('jiaOdd', this.n)// },// incrementWait() {// this.$store.dispatch('jiaWait', this.n)// }// 对象写法...mapActions({incrementOdd: 'jiaOdd', incrementWait: 'jiaWait'})// 同样是要对调用进行传参<button @click="incrementOdd(n)">当前求和为奇数再加</button><button @click="incrementWait(n)">等一等再加</button>
数组写法
...mapActions(['jiaOdd', 'jiaWait'])// 同样对函数名的调用就要修改了, 因为数组写法就会生成同名的函数名和调用属性<button @click="jiaOdd(n)">当前求和为奇数再加</button><button @click="jiaWait(n)">等一等再加</button>
学到这儿来个小总结:四个map方法的使用
-
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'])},
-
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使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。