Vue核心技术-55,Vuex-核心概念-Mutation

一,前言

在前面计数器程序的改写中,我们抛出了一个问题:
调用vuex中的mutation,为什么不是直接store.mutation.xxx
而是要store.commit('xxx')来实现

下面就来介绍vuex的又一个核心概念Mutation

二,vuex-Mutation

更改Vuex-store中状态的唯一方法就是提交mutation
Vuex中mutation类似于事件:
    每个mutation都有一个字符串的事件类型(type)和 一个回调函数(handler)
    回调函数就是实际进行状态更改的地方,

mutation接受state作为第一个参数:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    // 接受state作为第一个参数:
    increment (state) {
      // 变更状态
      state.count++
    }
  }
})
我们不能直接调用mutation handler
当触发一个类型为 increment 的 mutation 时,此函数才会被调用

要唤醒一个 mutation handler,需要以相应的 type 调用 store.commit 方法:

store.commit('increment')

还可以使用对象风格的提交方式:

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

三,提交载荷-Payload

向store.commit传入额外参数,作为mutation的载荷(payload):
mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

载荷可以是一个能包含多个字段的对象,使mutations更易读:

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

对象风格的提交方式:

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

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

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

四,使用常量替代Mutation事件类型

mutation中事件的命名使用大写的常量类型
将常量放在单独的文件中,让代码合作者对整个app包含的mutation一目了然

mutation-types.js:

export const SOME_MUTATION = 'SOME_MUTATION'

使用常量:

// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
  state: { ... },
  mutations: {
    // ES2015风格的计算属性命名功能,使用常量作为函数名
    [SOME_MUTATION] (state) {
      // mutate state
    }
  }
})

在多人协作的大型项目中,使用常量会很有帮助


五,Mutation必须是同步函数

mutation必须是同步函数

每一条mutation被记录时,devTools都需要捕捉前一状态和后一状态的快照

如果mutation中使用异步函数的回调这不可能完成
因为当mutation触发时,回调函数还未被调用,devtools不知道何时回调函数实际被调用

任何在回调函数中进行的状态的改变都是不可追踪的

在mutation中混合异步调用会导致程序难以调试

当调用两个包含异步回调的mutation来改变状态,哪个先回调是不可预知的,
所以,在Vuex中,mutation必须是同步事务

处理异步操作将由Action负责

将在vuex核心概念Action进行介绍

六,mapMutations辅助函数

在组件中可以使用this.$store.commit('xxx')提交mutation
也可以使用mapMutations辅助函数将组件中的methods映射为store.commit调用(需要在根节点注入 store)
import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      'increment', 

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

你可能感兴趣的:(Vue,Vue核心技术,vue,vuex,mutation)