一、同級 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。