mapMutations源码分析

367 阅读1分钟

mapMutations源码分析

  • 先来看一下 mapMutations 的使用示例:

引入官网(vuex.vuejs.org/zh/guide/mu…

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')`
    })
  }
}
  • 源码分析
/**
 * Reduce the code which written in Vue.js for committing the mutation
 * @param {String} [namespace] - Module's namespace
 * @param {Object|Array} mutations # Object's item can be a function which accept `commit` function as the first param, it can accept another params. You can commit mutation and do any other things in this function. specially, You need to pass anthor params from the mapped function.
 * @return {Object}
 */
export const mapmui = normalizeNamespace((namespace, mutations) => {  
  const res = {}
  if (__DEV__ && !isValidMap(mutations)) {
    console.error('[vuex] mapMutations: mapper parameter must be either an Array or an Object')
  }
  normalizeMap(mutations).forEach(({ key, val }) => {
    res[key] = function mappedMutation (...args) {
      // Get the commit method from store
      let commit = this.$store.commit
      if (namespace) {
        const module = getModuleByNamespace(this.$store, 'mapMutations', namespace)
        if (!module) {
          return
        }
        commit = module.context.commit
      }
      return typeof val === 'function'
        ? val.apply(this, [commit].concat(args))
        : commit.apply(this.$store, [val].concat(args))
    }
  })
  return res
})

改变函数的执行环境 同时把commit(this.store.commit)当做参数传给函数这里就可以解释为什么官网说的this.add()映射为this.store.commit)当做参数传给函数 这里就可以解释为什么官网说的`this.add()` 映射为 `this.store.commit('increment')`原因了

举例说明:例如mutations中的increment方法 在调用方式是这样子的:

...mapMutations({
    add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
  })

辅助函数处理之后其实是长这个样子的

this.$store.commit.apply(this.$store,[this.$store.commit].concat('increment')) 

最终你执行

mapMutations({
    add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
  })

其实执行的是 this.$store.commit('increment')