Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。 mutation 都是同步事务:

const store = new Vuex.Store({
  state: {
    count: 1,
  },
  mutations: {
    increment(state) {
      // 变更状态
      state.count++;
    },
  },
});
1
2
3
4
5
6
7
8
9
10
11

你不能直接调,需要用 store.commit 方法:

store.commit("increment");
1

提交载荷(传入参数)

// store.js
mutations: {
  increment (state, n) {
    state.count += n
  }
}
// App.vue
store.commit('increment', 10)
1
2
3
4
5
6
7
8

对象风格的提交方式

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

store.commit({
  type: "increment",
  amount: 10,
});
1
2
3
4

当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
1
2
3
4
5

Mutation 需遵守 Vue 的响应规则

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

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

  2. 当需要在对象上添加新属性时,你应该

  • 使用 Vue.set(obj, 'newProp', 123), 或者
  • 以新对象替换老对象。例如,利用对象展开运算符我们可以这样写:
state.obj = { ...state.obj, newProp: 123 };
1

Mutation 必须是同步函数

在组件中提交 Mutation

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

mapMutations 辅助函数

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')`
    }),
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Last Updated:
Contributors: websong