VueX的mutations、actions

一、更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型和一个回调函数,这个回调函数就是我们实际进行状态更改的地方,并且他会接受state作为第一个参数。

1、提交载荷

可以向store.commit传入额外的参数,即mutation的载荷

mutations:{

        increment(state,n){

                state.count += n        

        }

}

store.commit('increment',10)

大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的mutation会更易读

mutations:{
    increment (state,payload){
        state.count+=payload.amount
    }
}
store.commit('increment',{amount:10})

2、对象风格的提交方式

提交mutation的另一种方式是直接使用包含type属性的对象

store.commit({
    type:'increment',
    amount:10
})

当使用对象风格的提交方式,整个对象都作为载荷传给mutation函数,因此handler保持不变

mutations:{
    increment(state,payload){
        state.count += payload.amount
    }
}

3、mutation需遵守Vue的响应规则

既然Vuex的store中的状态是响应式的,那么当我们变更状态时,监视状态的Vue组件也会自动更新。意味着Vuex中的mutation也需要与使用Vue一样遵守一些注意事项

*最好提前在你的store中初始化好所有所需的属性

*当需要在对象上添加新属性时,应该使用Vue.set(obj,'newProp',123)或者

以新对象替换老对象,例如 利用对象展开运算符 

state.obj = { ...state.obj, newProp:123 }

4、使用常量替代mutation事件类型

mutations:{
    [SOME_MUTATION](state){
        
    }
}

5、mutation必须是同步函数

6、在组件中提交mutation

可以在组件中使用this.$store.commit('xxx')提交mutation,或者使用mapMutations辅助函数将组件中的methods映射为store.commit调用

import { mapMutations } from 'vuex'

export default {
    methods: {
        ...mapMutations(
            [
                'increment',   //将this.increment()映射为this.$store.commit('increment') 
                //mapMutations也支持载荷
                'incrementBy'   //将this.incrementBy(amount)映射为this.$store.commit('incrementBy',amount)
            ]
        ),
        ...mapMutations({
            add:'increment'  //将this.add()映射为this.$store.commit('increment')
        })
    }
}

二、Action

1、action类似于mutation,然而action提交的是mutation,而不是直接变更状态;action可以包含任意异步操作

const store = new Vuex.Store({
    state: {
       count: 0
    },
    mutations: {
        increment (state){
            state.count++
        }
    },
    actions:{
        increment (context) {
            context.commit('increment')
        }
    }
})

action函数接受一个与store实例具有相同方法和属性的context对象,因此你可以调用context.commit提交一个mutation,或者通过context.state和context.getters来获取state和getters。

实践中,我们会经常用到ES2015的参数解构来简化代码

actions: {
    increment ({commit}){
        commit('increment')
    }
}

2、分发Action

action通过store.dispatch方法触发

store.dispatch('increment')

由于mutation必须同步执行,直接分发mutation是不可以的,而action不会受限制,我们可以在action内部执行任意异步操作 

actions :{
    incrementAsync({commit}){
        setTimeout(()=>{
            commit('increment')
        },1000)
    }
}

action支持同样的载荷方式和对象进行分发

store.dispatch('incrementAsync',{
    amount: 10
})

store.dispatch({
    type:'incrementAsync',
    amount" 10
})

3、在组件中分发action

在组件中使用this.$store.dispatch('xxxx')分发action,或者使用mapActions辅助函数组件的methods映射为store.dispatch调用(需要先在根节点注入store)

import { mapActions } from 'vuex'

export default {
    methods :{
        ...mapActions([
            'increment',   //将 this.increment() 映射为 this.$store.dispatch('increment')
            //mapActions 也支持载荷
            'incrementBy'  //将 this.incrementBy(amount) 映射为 this.$store.dispatch('incrementBy',amount)
        ]),
        ...mapActions({
            add: 'increment'  //将this.add() 映射为 'this.$store.dispatch('increment')'
        })
}
}

4、组合action

store.dispatch可以处理被触发的action的处理函数返回的promise,并且store.dispatch仍旧返回promise

actions: {
    actionA({ commit }){
        return new Promise((resolve, reject)=>{
            setTimeout(()=>{
                commit('someMutation')
                resolve()
            }, 1000)
        })
    }
}

可以这样

store.dispatch('actionA').then(()=>{
    //...
})

在另外一个action中也可以

action: {
    actionB({ dispatch, commit}){
        return dispatch('actionA').then(()=>{
            commit('someOtherMutation')
        })
    }
}

最后可以利用async和await进行组合action

//假设getData() 和 getOtherData() 返回的是Promise

actions: {
    async actionA ({ commit }) {
        commit('gotData', await getData())
    },
    async actionB ({ dispatch, commit }) {
        await dispatch('actionA')
        commit('gotOtherData', await getOtherData())
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值