天天看点

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

文章目录

  • ​​getters配置项​​
  • ​​mapState与mapGetters​​
  • ​​mapActions与mapMutations​​
  • ​​四种map映射方法的总结​​

getters配置项

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

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

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

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

......

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

//创建并暴露store
export default new Vuex.Store({
  ......
  getters
})      
Vuex③(getters,四种map映射方法)
state与getters的关系,就如同data与computed的关系

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

步骤二:组件中读取数据

我们可以在store的getters中找到他:

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

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

<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:

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

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有关的:
Vuex③(getters,四种map映射方法)

首先我们要引入它:

import {mapState} from 'vuex'      

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

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

我们可以把它打印出来看看:

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

他是对象,其中的每一个函数等价于刚才的计算属性

所以我们可以利用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
      },
         },      

结果:

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

​mapState​

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

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

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

​mapGetters​

这个函数的使用方法与​

​mapState​

​一模一样

有一个注意点:

如果你使用的计算属性,那么在开发者工具中显示:

Vuex③(getters,四种map映射方法)
如果你使用的映射方式,那么在开发者工具中显示:
Vuex③(getters,四种map映射方法)

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​

​方法来生成代码

与前面不同的是:

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

上面是原方法,而下面是我们使用​

​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>      
如果我们在回调时不传入参数,那么其实传的就是默认的事件对象:
Vuex③(getters,四种map映射方法)

然后下面的两个方法(使用了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映射方法的总结

  1. mapState方法:用于帮助我们映射​

    ​state​

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

    ​getters​

    ​中的数据为计算属性
computed: {
    //借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters({bigSum:'bigSum'}),

    //借助mapGetters生成计算属性:bigSum(数组写法)
    ...mapGetters(['bigSum'])
},      
  1. mapActions方法:用于帮助我们生成与​

    ​actions​

    ​对话的方法,即:包含​

    ​$store.dispatch(xxx)​

    ​的函数
methods:{
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])
}      
  1. mapMutations方法:用于帮助我们生成与​

    ​mutations​

    ​对话的方法,即:包含​

    ​$store.commit(xxx)​

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

继续阅读