在 Vuex 狀態管理套件管理 API 呼叫狀態

前言

每一個 API 有各自不同的呼叫狀態,比如 loading 代表正在呼叫、loaded 代表呼叫成功,而 error 則代表呼叫失敗。為了簡化在 Vuex 中有關呼叫狀態的程式碼,以下實作一個共用的類別,用來處理各自的 API 呼叫狀態。

做法

store/modules 資料夾建立一個 base 類別,用來封裝 API 的回傳結果和呼叫狀態:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
export default class Base {
static state() {
return {
data: null,
status: {
loading: false,
loaded: false,
error: null,
},
};
}

static update(state, payload = null) {
if (!payload) {
state.data = null;
state.status.loading = true;
state.status.loaded = false;
state.status.error = null;
return state;
}

if (payload instanceof Error) {
state.data = null;
state.status.loading = false;
state.status.loaded = true;
state.status.error = payload;
return state;
}

state.data = payload;
state.status.loading = false;
state.status.loaded = true;
state.status.error = null;
return state;
}
}

Base 類別匯入到每個模組,並使用 Base 類別提供的原始狀態封裝 API 的回傳結果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import axios from 'axios';
import Base from '@/store/modules/base';

export default {
namespaced: true,
state: {
items: Base.state(), // 原始狀態
},
mutations: {
setItems(state, payload) {
state.items = Base.update(state.items, payload); // 更新狀態
},
},
actions: {
fetchItems({
commit,
}, {
page,
}) {
commit('setItems'); // 設置狀態為正在呼叫
return new Promise((resolve, reject) => {
axios({
method: 'GET',
url: '/items',
params: {
page,
per_page: 100,
},
})
.then(({ data }) => {
commit('setItems', data.data); // 設置狀態為呼叫成功
resolve(data);
})
.catch((error) => {
commit('setItems', error); // 設置錯誤
reject(error);
});
});
},
},
};

參考資料