四月 26, 2019 | 前端與Vue

[Nuxt 教學] vuex設定及nuxtServerInit一次接收多組api

作者近期嘗試使用vuex管理專案所需之共用資料,原先只需接收一組api,因需求接收第二組api時卻發現始終只能接收一組api,其實是設定上發生了小錯誤,讓我們來看看有哪些設定要注意吧! step.1 設定vuex 接下來的步驟可配合官方文件一起服用,~~功效會加倍哦~~~ vuex官方文件:點我 此範例在nuxt環境下應建立在根目錄的store裡面,可單獨寫一個js或者將state、getters、mutations、actions分開寫成四個js檔,再由index.js import 4個js,作者使用第二種方式管理,如下圖所示。

作者近期嘗試使用vuex管理專案所需之共用資料,原先只需接收一組api,因需求接收第二組api時卻發現始終只能接收一組api,其實是設定上發生了小錯誤,讓我們來看看有哪些設定要注意吧!

step.1 設定vuex

接下來的步驟可配合官方文件一起服用,~~功效會加倍哦~~~
vuex官方文件:點我
此範例在nuxt環境下應建立在根目錄的store裡面,可單獨寫一個js或者將state、getters、mutations、actions分開寫成四個js檔,再由index.js import 4個js,作者使用第二種方式管理,如下圖所示。

import Vuex from 'vuex'
import { state } from './state.js'
import { getters } from './getters.js'
import { mutations } from './mutations.js';
import { actions } from './actions.js';

const createStore = () => {
  return new Vuex.Store({
    state,
    getters,
    mutations,
    actions,
  })
}

export default createStore

這樣就完成初步的vuex設定,可以開始管理我們的資料!
接下來第一個步驟先到state定義所需的資料,範例如下:

export const state = {
//定義為空陣列
WorksCategories:[]
//直接詳細定義
workclassification:{
 WorkCategory:'ALL',
 List:[]
 }
}

step.2 getters

為何要定義getters?不能直接用state定義的資料嗎?
其實官方文件有提到,若取用vuex的資料要做進一步處理,應盡量避免直接取用state的資料並計算,這時getters就登場啦!
可以把getters當成vue的components,getters接收state當成第一個參數,等同於取用state相同的資料卻不影響state的原始狀態,了解原理後我們來定義getters吧!

export const getters = {

worklist:(state, getters) => {
 return state.workclassification.List;
}


step.2 mutations

前面步驟定義完資料後,現在要開始寫資料的狀態,此階段是唯一能修改store資料狀態的地方。
step1的state若直接取用修改其實能正常工作,但在嚴格模式下會報錯,還是照著流程定義getters後使用mutation提交修改狀態才是好的開發流程。

export count mutations {
 SaveWork(state, context){
  state.workclassification = context;
  //context可自行定義
 }
}

step.3 actions

actions 跟 mutations很像,不同之處在於:

  • Action 提交的是 mutation,而不是直接變更狀態。
  • Action 可以包含任意非同步操作。
export count actions {
 async nuxtServerInit({ commit }){
  const { data } =await this.$axios.get('你要介接的api')
  commit('指定你要mutations', data)
 },
}

以上步驟都完成進入頁面開啟vue devtools查看state及getters可以看到介接的api資料,如下圖所示:

這時可以看到我們在state及getters定義的workclassification有接收到api內的資料。


一次接多組api

本文精華來了,如果想介接兩組以上api,寫法需改變:
(本文已事先在state、getters、mutations定義相關聯的兩組資料)

export count actions {

 async nuxtServerInit({ commit, dispatch }) {
  await dispatch('storeWorksCategories')
  return await dispatch('SaveWork')
  }
  
 async storeWorksCategories({ commit }) {
  const { data } =await this.$axios.get('第一組api')
    var categories=[];
    data.data.forEach(element => {
        var obj={
                tid: 定義對應的api資料,
                name: 定義對應的api資料,
                path: 定義對應的api資料
            };
        categories.push(obj);
    });
    commit("storeWorksCategories", categories);
},

//第二組api
async SaveWork({ commit }){
  const { data } =await this.$axios.get('第二組api')
  commit('SaveWork', data)
 }
}

先來聊聊await,原先只有一組api時使用async 跟 await 能順利接到api,但兩組以上則會有衝突,為什麼呢?
在上面程式碼中可以看到第二個dispatch的await 前寫了 return,如果沒有寫return的話await會卡住,只會接收到第二組的api。
你可以將return改寫到第一個dispatch測試,第二組api就不會接收到了。


結論

使用vuex集中管理資料有非常多好處,剛進入網頁如果state跟getters已經讀取好資料,後續要使用就不用重複讀取,可以增加網頁的效能,而且網頁的每個地方都能直接使用vuex的資料,越大型的專案越應該有良好的vuex控管,剛好此次遇到在vuex一次接收多組api,希望閱讀完此篇的讀者能對vuex有初步的了解也一並解決類似問題。

hashtags: