天天看點

vuex 中 actions 如何各個子產品間,互相調用 actions、mutations、state 等資訊

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

繼續閱讀