vuex中commit和dispatch

image.png

当我们创建一个vuex时候,也就是创建一个store实例。我们使用vuex其实也就是对store实例的使用

import Vuex from 'vuex'

const store = new Vuex.Store({ ...options })

关于mutations

当我们使用mutations时,其实也就是在store实例上注册一个mutation。因为mutation处理函数总是接受 state 作为第一个参数(如果定义在模块中,则为模块的局部状态),第二个参数可选。这也就是为什么我们可以store.commit('func')来调用相对应的mutation

//vuex/src\store.js vuex源码
this.commit = function boundCommit (type, payload, options) {
      return commit.call(store, type, payload, options)
    }

关于actions

当我们使用actions时,其实也是在store上注册 action。处理函数总是接受 context 作为第一个参数。关于context其实是个对象,包含以下属性:

{
  state,      // 等同于 `store.state`,若在模块中则为局部状态
  rootState,  // 等同于 `store.state`,只存在于模块中
  commit,     // 等同于 `store.commit`
  dispatch,   // 等同于 `store.dispatch`
  getters,    // 等同于 `store.getters`
  rootGetters // 等同于 `store.getters`,只存在于模块中
} 

这也是为什么我们可以使用store.dispatch('increment')来分发action。


当我们使用store.dispatch('increment')时,会在当前store实例上的_actionSubscribers数组中根据传入的type来遍历查找相对应的action来触发相对应的mutation

dispatch (_type, _payload) {
    const action = { type, payload }
    const entry = this._actions[type]
    const result = entry.length > 1
      ? Promise.all(entry.map(handler => handler(payload)))
      : entry[0](payload)
    return new Promise((resolve, reject) => {
      result.then(res => {
        try {
          this._actionSubscribers
            .filter(sub => sub.after)
            .forEach(sub => sub.after(action, this.state))
        } catch (e) {
          if (__DEV__) {
            console.warn(`[vuex] error in after action subscribers: `)
            console.error(e)
          }
        }
        resolve(res)
      }
}

而我们通过commit来遍历_mutations处理相对应的mutation handler

commit (_type, _payload, _options) {
    const mutation = { type, payload }
    const entry = this._mutations[type]
    this._withCommit(() => {
      entry.forEach(function commitIterator (handler) {
        handler(payload)
      })
    })
  }

你可能感兴趣的:(vuex中commit和dispatch)