Appearance
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)
}
总结
- 其不是按照树结构存储在 store 下的,而是按照命令空间扁平化的方式通过 getNamespace() 方法生成其唯一的字符串 key 存储在
store._actions
下