第四十四节:Vuex状态管理:辅助函数mapMutations与mapActions

前言说明:
  1. 大家已经知道vuex提供了mapStatemapGetter方法,方便我们获取stategetters

  2. 同样的vuex也提供了mapMutationsmapActions方便操作mutationsactions方法

  3. 需要注意的是mapStatemapGetter是映射为计算属性,获取数据

  4. mapMutationsmapActions是映射为组件methods方法,修改数据的


1. 未使用辅助函数修改转台

1.1 设置修改状态的mutations和actions

代码如下

let store = new Vuex.Store({
    state:{
        count:0,
        user:{
            name:"张三",
            age:20
        },
        fruits:[{
            name:"苹果",
            price: 22
        },{
            name:"梨子",
            price: 25
        },{
            name:"西瓜",
            price: 16
        },{
            name:"香蕉",
            price: 18
        }]
    },
    getters:{
        filterFruits(state){
            return state.fruits.filter(fruit => fruit.price > 20)
        }
    },
    // 定义mutations
    mutations:{
        // 同步修改状态count
        increment(state, payload){
            state.count++
        }
    },
    actions:{
        // 异步修改状态count
        asyncIncrement(context){
            setTimeout(function(){
                context.commit({
                    type:"increment"
                })
            },1000)
        }
    },

})

示例说明

  1. 组件中如果通过commit触发mutation函数,就会同步更改状态count
  2. 组件中如果通过dispath异步触发action函数,
  3. action会异步触发mutation函数,通过mutation修改状态


1.2 组件中触发mutation和action
<template>
<div class="home">
    <div class="count">数字: {{ count }}</div>
    <button @click="increment">同步++</button>
    <button @click="asyncincrement">异步++</button>

    </div>
</template>

<script>
    // 获取辅助函数
    import {mapState,mapGetters} from 'vuex'

    export default {
        name: 'Home',
        data(){
            return {
                // count: 10
                price: 10
            }
        },
        computed:{
            computePrice(){
                return this.price * 2
            },
            ... mapState([
                "count",
                "user",
                "fruits"
            ]),
            ...mapGetters([
                "filterFruits"
            ])
        },
        methods:{
            increment(){
                // 同步,通过commit触发mutation函数
                this.$store.commit({
                    type:"increment"
                })

            },
            asyncincrement(){
                // 异步,通过dispatch 触发action函数
                this.$store.dispatch({
                    type:"asyncIncrement"
                })
            }
        }
    }
</script>

示例说明:

  1. increment是触发mutation同步修改状态的方法
  2. asyncIncrement是触发action异步修改状态的方法


2. 使用mapMutations

说明:

  1. 之前如果我们需要在组件中修改store的状态都需要额外定义一个方法
  2. 如果这个方法里有大量的逻辑代码还好
  3. 如果这个方法只是为了触发mutation函数,每个组件都这样定义就会比较繁琐
  4. 因此vuex提供了mapMutations辅助函数,可以将mutations函数映射为组件methods方法


2.1 方法同名

方法同名意思就是组件用来触发mutation函数的方法和mutation函数重名

就可以采用字符串数组的的方式将mutation函数通过函数名映射methods方法

数组里的字符串为mutations的函数名

代码如下:

// 通过vuex获取辅助函数
import {
    mapState,   // 获取state辅助函数
    mapGetters, // 获取getters 辅助函数
    mapMutations, // 操作mutations辅助函数
} from 'vuex'

export default {
    name: 'Home',
    data(){
        return {
            // count: 10
            price: 10
        }
    },
    computed:{
        computePrice(){
            return this.price * 2
        },
        ... mapState([
            "count",
            "user",
            "fruits"
        ]),
        ...mapGetters([
            "filterFruits"
        ])
    },
    methods:{
        ...mapMutations([
            'increment'  
            //  将this.increment 映射为 this.$store.commit("increment")
        ]),
        asyncincrement(){
            // 异步,通过dispatch 触发action函数
            this.$store.dispatch({
                type:"asyncIncrement"
            })
        }
    }
}


2.2 关于载荷

此时是将mutation函数映射为组件methods方法,

如果此时调用这个方法不传参数时, 那么将没有载荷

例如:

 <button @click="increment">同步++</button>

如果在调用这个映射方法是传递一个数据,那么这个数据将成为mutation函数的载荷

 <button @click="increment(10)">同步++</button>

一般来说,载荷会选择对象方式传递数据

 <button @click="increment({num:10})">同步++</button>


2.3 方法不同名

也就是需要映射到组件方法中的mutation函数,在组件中已经有同名的函数了

因此在映射时,就需要另外定义方法名

此时组件中被映射的方法名和mutation函数名就不同名了

此时需要选择对象的方式映射

代码如下:

// 通过vuex获取辅助函数
import {
    mapState,   // 获取state辅助函数
    mapGetters, // 获取getters 辅助函数
    mapMutations, // 操作mutations辅助函数
} from 'vuex'

export default {
    name: 'Home',
    data(){
        return {
            // count: 10
            price: 10
        }
    },
    computed:{
        computePrice(){
            return this.price * 2
        },
        ... mapState([
            "count",
            "user",
            "fruits"
        ]),
        ...mapGetters([
            "filterFruits"
        ])
    },
    methods:{
        ...mapMutations({
            // 方法名: mutation函数名
            add:'increment'  
            
            //  将this.add 映射为 this.$store.commit("increment")
        }),
        asyncincrement(){
            // 异步,通过dispatch 触发action函数
            this.$store.dispatch({
                type:"asyncIncrement"
            })
        }
    }
}


3. 使用mapActions

mapActions辅助函数的使用和mapMutations一样

同样也可以传递载荷

因此可以将代码修改如下

// 通过vuex获取辅助函数
import {
    mapState,   // 获取state辅助函数
    mapGetters, // 获取getters 辅助函数
    mapMutations, // 操作mutations辅助函数
    mapActions    // 操作actions辅助函数
} from 'vuex'

export default {
    name: 'Home',
    data(){
        return {
            // count: 10
            price: 10
        }
    },
    computed:{
        computePrice(){
            return this.price * 2
        },
        ... mapState([
            "count",
            "user",
            "fruits"
        ]),
        ...mapGetters([
            "filterFruits"
        ])
    },
    methods:{
        ...mapMutations({
            // 方法名: mutation函数名
            add:'increment'  

            //  将this.add 映射为 this.$store.commit("increment")
        }),
        ...mapActions([
            "asyncIncrement"
            
            // 将this.asyncIncrement 
            // 映射为 this.$store.dispatch("asyncIncrement")
        ])
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342