Skip to content

Action

使用方式

js
moduleABA.actions: {
  // ...
  increment (context)  {
      context.commit('increment')
    }
}

store.store.dispatch("moduleA/modueleAB/modueleABA/increment") // -> 1

初始化阶段

遍历处理 module 中的 actions 属性,将每一个 action 按照以其 namespaced + / + actionNameKey为 key 存储到 store._actions[type]下。这样上面moduleA/modueleAB/modueleABA/increment就会变成 store._actions["moduleA/modueleAB/modueleABA/increment"] = () => {}

这边根 action 一样两组不同的对象 local.state store.state

js
/**
 * 处理 module中的 actions 属性
 * @param {*} store      store实例对象
 * @param {*} type       action的全路径名称 如: ‘a/aa/aaa/action1’
 * @param {*} handler    定义的处理函数 hander
 * @param {*} local
 */
function registerAction(store, type, handler, local) {
  //以action的全路径名称为key 保存在 store._actions上
  const entry = store._actions[type] || (store._actions[type] = [])
  entry.push(function wrappedActionHandler(payload, cb) {
    let res = handler.call(
      store,
      {
        dispatch: local.dispatch,
        commit: local.commit,
        getters: local.getters,
        state: local.state,
        rootGetters: store.getters,
        rootState: store.state,
      },
      payload,
      cb
    )
    if (!isPromise(res)) {
      res = Promise.resolve(res)
    }
    if (store._devtoolHook) {
      return res.catch(err => {
        store._devtoolHook.emit("vuex:error", err)
        throw err
      })
    } else {
      return res
    }
  })
}

action 的访问

访问方式为 store._actions["moduleA/modueleAB/modueleABA/increment"] = () => {}

核心源码为:

js
function dispatch(_type, _payload) {
  // check object-style dispatch
  // 处理入参 提供两种方式 传递 type, payload, options
  const { type, payload } = unifyObjectStyle(_type, _payload)
  const action = { type, payload }
  const entry = this._actions[type]
  if (!entry) {
    if (process.env.NODE_ENV !== "production") {
      console.error(`[vuex] unknown action type: ${type}`)
    }
    return
  }
  // 回调用户订阅的 action回调方法  store.subscribeAction(() => {})
  //  主要给插件使用的
  this._actionSubscribers.forEach(sub => sub(action, this.state))
  // 回调action
  return entry.length > 1 ? Promise.all(entry.map(handler => handler(payload))) : entry[0](payload)
}

总结

  1. 其不是按照树结构存储在 store 下的,而是按照命令空间扁平化的方式通过 getNamespace() 方法生成其唯一的字符串 key 存储在 store._actions