vuex (4)

Mutation 

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

const store = createStore({

       state: {
              count : 1
       },
 
       mutations: {
             increment(state){
                  // 变更状态
                  state.count++;
            }     
      }
})

 

 你不能直接调用一个mutation处理函数,这个选项更像是事件注册:“当触发一个类型为 increment” 的mutation时,调用此函数。

 要唤醒一个mutation处理函数,你需要以相应的type调用 store.commit 方法:

store.commit方法

 

提交载荷 Payload

向store.commit 传入额外的参数,即mutation 的 载荷 (payload)

// ...

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
})

 

对象风格的提交方式

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

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

 

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

 

Mutation 必须是同步函数

一条重要原则就是要记住 mutation 必须是同步函数,为什么呢?

mutations: {

    someMutation (state){
         api.callAsyncMethod(() => {
                 state.count++;
         })
    }
}

现在想象,我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools都需要捕捉到前一状态和后一状态的快照,然而,在上面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用, devtools 不知道什么时候回调函数实际上被调用------实质上任何在回调函数中进行的状态改变都是不可追踪的。

 

在组件中使用 this.$store.commit("xxx") 提交mutation , 或者使用 mapMutations 辅助函数将组件中的methods映射为 store.commit 调用 (需要在根节点注入store)。

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')`
           })
     }
}

 

当你调用了两个包含异步回调的mutation来改变状态,你怎么知道什么时候回调和哪个先回调呢? 因此,在Vuex中, mutation都是同步事务

posted on 2022-02-11 11:14  zhishiyv  阅读(28)  评论(0编辑  收藏  举报

导航