一、同级 actions 调用
对于同级模块下的 actions,如何互相调用呢?
实现方式:分发 action,action 通过 store.dispatch 方法触发。
二、不同模块 actions 调用
由于 Vuex 使用了单一状态树,应用的所有状态都包含在一个大对象中。那么,随着应用的不断扩展,store 会变得非常臃肿。
为了解决这个问题,Vuex 允许我们把 store 分 module(模块)。每一个模块包含各自的状态、mutation、action 和 getter。
vuex 中 modules 可以将项目的 state 进行分块,互不干扰。那么在单个 moudule 中,actions 如何调用其他模块的 actions 或者根 actions、mutations、state ?
actions 中提供如下方法:
rootGetters 用于获取其他模块getter; rootState 用于获取其它模块state; getters 用于获取当前模块getter; state 用于获取当前模块state; dispatch 用于调用action,当前模块和其他模块; commit 用于调用mutation,当前模块和其他模块; (一)rootGetters
const user = {
......
actions: {
async changeUser ({ rootGetters }) {
console.log(rootGetters) // 根 getters 与其他模块 getters 下的信息
},
}
}
export default user
(二)rootState
rootState 与上述 rootGetters 同样的,获取根 state 和 其他模块 state 下的信息。
可用于:模块 B 的 actions 里,调用模块 A 的 state。
(三)getters
const user = {
......
getters: {
name: state => state.username
},
actions: {
async changeUser ({ getters }) {
console.log(getters) // 当前模块中的 getters 信息
},
}
}
export default user
(四)state
state 与上述 getters 同样的,只能获取当前模块中 state 信息。
(五)dispatch
如果同级模块的 action 调用,我们使用 dispatch 来触发;
如果在根文件下,定义一个 log 方法,通过 dipatch 去调用,则可以通过 root 参数:
const user = {
......
getters: {
name: state => state.username
},
actions: {
async changeTime ({ dispatch }, time) {
dispatch('log', { time }, { root: true })
},
}
}
export default user
根模块 index.js 文件下:
const store = new Vuex.Store({
actions: {
log({}, { time }) {
console.log(time)
}
},
})
export default store
模块 B 的 actions,需要调用模块 A 的 actions 时,可以使用 root: true 实现。这里 dispatch 的第一个参数,需要传入其他模块的 actions 路径,第二个参数为传给 actions 的数据,若不传,也需要预留,第三个参数是配置选项,申明这个 actions 不是当前模块的;
(六)commit
commit 触发 mutations,从而同步更新state,如:
const user = {
state: {
token: '',
},
mutations: {
setToken: (state, token) => {
state.token = token
},
},
actions: {
async Login ({ commit }, userInfo) {
const { username, password } = userInfo
const resp = await api.login({ username, password })
const { tokenInfo } = resp.data
commit('setToken', tokenInfo.token)
},
}
}
export default user
如果想触发其他模块的mutation动态更新state,则需要借助参数root:
首先在根模块 index.js 文件下:
import user from './modules/user'
import home from './modules/home'
const store = new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {},
/* 最好能够根据功能划分模块,将业务代码写在vuex里,尽可能地将视图层(vue)和领域层(vuex)分离 */
modules: {
user,
home,
}
})
export default store
然后在 home.js 文件的模块下:
const home = {
......
actions: {
async changeToken ({ commit }, token) {
commit('user/setToken', token, { root: true }) // 重点
},
}
}
export default home
总结:commit 是调用 mutations 用的,dispatch 是调用 actions 用的,state 是当前模块的 state,而 rootState 是根 state 和其他模块的 state。