Vuex③(getters,四种map映射方法)

41 篇文章 1 订阅

getters配置项

当state中的数据需要经过加工后再使用时,可以使用getters加工。

它与计算属性computed有些类似,但是它与计算属性的不同点在于,其可以在任意组件中复用,而计算属性只在当前组件中生效。

那么它如何使用呢,我们举一个例子,在求和案例的基础上,将和放大十倍展示:

步骤一:我们先在store中添加getter配置项

......

const getters = {
	bigSum(state){
		return state.sum * 10
	}
}

//创建并暴露store
export default new Vuex.Store({
	......
	getters
})

在这里插入图片描述
state与getters的关系,就如同data与computed的关系

这里于计算属性的写法一样,不过我们的方法中会传入一个参数state。

步骤二:组件中读取数据

我们可以在store的getters中找到他:
在这里插入图片描述

于是我们的代码可以这么写:

<template>
	<div>
		<h1>当前求和为:{{$store.state.sum}}</h1>
		<h3>当前求和放大10倍为:{{$store.getters.bigSum}}</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
		<button @click="incrementWait">等一等再加</button>
	</div>
</template>

在开发者工具中我们可以查看getters:
在这里插入图片描述

mapState与mapGetters

我们在完成求和案例的时候会发现,我们要呈现一个数据的时候前面要加一些重复繁冗的前缀,如果要呈现的数据变得很多,那么就会变得非常的麻烦,例如:

<template>
    <div>
        <h1>当前求和为:{{$store.state.sum}}</h1>
        <h1>当前求和放大10倍为:{{$store.getters.bigSum}}</h1>
        <h1>学生姓名:{{$store.state.student}}</h1>
        <h1>学校名称:{{$store.state.school}}</h1>

        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一等再加</button>
    </div>
</template>

我们有一种解决办法就是使用计算属性computed:

<template>
    <div>
        <h1>当前求和为:{{sum}}</h1>
        <h1>当前求和放大10倍为:{{bigSum}}</h1>
        <h1>学生姓名:{{student}}</h1>
        <h1>学校名称:{{school}}</h1>

        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一等再加</button>
    </div>
</template>

<script>
    export default {
        name:'MyCount',
        data() {
            return {
                n:1, //用户选择的数字
            }
        },
        computed:{
            //靠程序员自己亲自去写计算属性
            sum(){
                return this.$store.state.sum
            },
            school(){
                return this.$store.state.school
            },
            student(){
                return this.$store.state.student
            },
            bigSum(){
				return this.$store.getters.bigSum
			},
         },
		 ······
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }
</style>

我们观察这些计算属性可以发现一些规律,于是我们可以借助Vuex中为我们生成代码的函数,只需传入几个简单的参数就可以达到同样的效果,这个方法就是mapState

这个方法能帮我们生成前三个计算属性,也就是跟state有关的:
在这里插入图片描述

首先我们要引入它:

import {mapState} from 'vuex'

其次这个方法可以传入一个对象:

  • 对象的键记录计算属性的名
  • 对象的值记录其在state中对应的名字
mapState({sum:'sum',school:'school',student:'student'})

我们可以把它打印出来看看:
在这里插入图片描述
他是对象,其中的每一个函数等价于刚才的计算属性

所以我们可以利用ES6的语法,把这个对象解构放入到计算属性中:

       computed:{
            //靠程序员自己亲自去写计算属性
            // sum(){
            //     return this.$store.state.sum
            // },
            // school(){
            //     return this.$store.state.school
            // },
            // student(){
            //     return this.$store.state.student
            // },
            ...mapState({sum:'sum',school:'school',student:'student'}),
            bigSum(){
				return this.$store.getters.bigSum
			},
         },

结果:
在这里插入图片描述

mapState这个方法还有另一种写法,他可以传入一个数组。如果你在使用第一种方法的时候发现键和值一模一样就可以使用这种写法:

...mapState(['sum','school','student'])

接下来我们解决getters的问题,它也有一个对应的函数mapGetters

这个函数的使用方法与mapState一模一样

有一个注意点:
如果你使用的计算属性,那么在开发者工具中显示:
在这里插入图片描述
如果你使用的映射方式,那么在开发者工具中显示:
在这里插入图片描述

mapActions与mapMutations

接下来我们来优化methods中的代码:

       methods: {
            increment(){
                this.$store.commit('JIA',this.n)
            },
            decrement(){
                this.$store.commit('JIAN',this.n)
            },
            incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                this.$store.dispatch('jiaWait',this.n)
            },
        },

首先我们可以看到上面两个方法,都是用了commit,而commit是用来与mutations对话的(Vuex原理图),所以在这里我们使用mapMutations方法来生成代码

与前面不同的是:
在这里插入图片描述
上面是原方法,而下面是我们使用mapMutations方法生成的,由此我们知道这个this.n我们要在调用的时候传进去,而不是通过mapMutations来传。其他的使用与前文所提到的mapState与mapGetters一样。

代码如下:

<template>
    <div>
        <h1>当前求和为:{{sum}}</h1>
        <h1>当前求和放大10倍为:{{bigSum}}</h1>
        <h1>学生姓名:{{student}}</h1>
        <h1>学校名称:{{school}}</h1>

        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一等再加</button>
    </div>
</template>

<script>
    import {mapState,mapGetters,mapMutations} from 'vuex'
    export default {
        name:'MyCount',
        data() {
            return {
                n:1, //用户选择的数字
            }
        },
        computed:{
            //靠程序员自己亲自去写计算属性
            // sum(){
            //     return this.$store.state.sum
            // },
            // school(){
            //     return this.$store.state.school
            // },
            // student(){
            //     return this.$store.state.student
            // },
            ...mapState({sum:'sum',school:'school',student:'student'}),
            // bigSum(){
			// 	return this.$store.getters.bigSum
			// },
            ...mapGetters(['bigSum']),
         },
        methods: {
            // increment(){
            //     this.$store.commit('JIA',this.n)
            // },
            // decrement(){
            //     this.$store.commit('JIAN',this.n)
            // },
            ...mapMutations({increment:'JIA',decrement:'JIAN'}),
            incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                this.$store.dispatch('jiaWait',this.n)
            },
        },
        mounted() {
            // console.log(mapState({sum:'sum',school:'school',student:'student'}))
        },
    }
</script>

如果我们在回调时不传入参数,那么其实传的就是默认的事件对象:
在这里插入图片描述

然后下面的两个方法(使用了dispatch,与Actions对话)我们使用mapActions方法进行生成

完整优化代码如下:

<template>
    <div>
        <h1>当前求和为:{{sum}}</h1>
        <h1>当前求和放大10倍为:{{bigSum}}</h1>
        <h1>学生姓名:{{student}}</h1>
        <h1>学校名称:{{school}}</h1>

        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前求和为奇数再加</button>
        <button @click="incrementWait(n)">等一等再加</button>
    </div>
</template>

<script>
    import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
    export default {
        name:'MyCount',
        data() {
            return {
                n:1, //用户选择的数字
            }
        },
        computed:{
            //靠程序员自己亲自去写计算属性
            // sum(){
            //     return this.$store.state.sum
            // },
            // school(){
            //     return this.$store.state.school
            // },
            // student(){
            //     return this.$store.state.student
            // },
            ...mapState({sum:'sum',school:'school',student:'student'}),
            // bigSum(){
			// 	return this.$store.getters.bigSum
			// },
            ...mapGetters(['bigSum']),
         },
        methods: {
            // increment(){
            //     this.$store.commit('JIA',this.n)
            // },
            // decrement(){
            //     this.$store.commit('JIAN',this.n)
            // },
            ...mapMutations({increment:'JIA',decrement:'JIAN'}),
            // incrementOdd(){
            //     this.$store.dispatch('jiaOdd',this.n)
            // },
            // incrementWait(){
            //     this.$store.dispatch('jiaWait',this.n)
            // },
            ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
        },
        mounted() {
            // console.log(mapState({sum:'sum',school:'school',student:'student'}))
        },
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }
</style>

四种map映射方法的总结

四个map方法的使用

  1. mapState方法:用于帮助我们映射state中的数据为计算属性

    computed: {
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
  2. mapGetters方法:用于帮助我们映射getters中的数据为计算属性

    computed: {
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)
        ...mapGetters(['bigSum'])
    },
    
  3. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

    methods:{
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //靠mapActions生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

    methods:{
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    

备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十八岁讨厌编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值