一、概述
原文地址:https://pro.ant.design/docs/server-cn
Ant Design Pro 是一套基於 React 技術棧的單頁面應用,我們提供的是前端代碼和本地模擬數據的開發模式, 通過 Restful API 的形式和任何技術棧的服務端應用一起工作。下面將簡單介紹和服務端交互的基本寫法。
二、詳細介紹
2.1、前端請求流程
在 Ant Design Pro 中,一個完整的前端 UI 交互到服務端處理流程是這樣的:
-
UI 組件交互操作;
-
調用 model 的 effect;
-
調用統一管理的 service 請求函數;
-
使用封裝的 request.js 發送請求;
-
獲取服務端返回;
-
然后調用 reducer 改變 state;
-
更新 model。
從上面的流程可以看出,為了方便管理維護,統一的請求處理都放在 services 文件夾中,並且一般按照 model 維度進行拆分文件,如:
services/ user.js api.js ...
其中,utils/request.js 是基於 fetch 的封裝,便於統一處理 POST,GET 等請求參數,請求頭,以及錯誤提示信息等。具體可以參看 request.js。
例如在 services 中的一個請求用戶信息的例子:
// services/user.js
import request from '../utils/request';
export async function query() {
return request('/api/users');
}
export async function queryCurrent() {
return request('/api/currentUser');
}
models
// models/user.js
import { queryCurrent } from '../services/user';
...
effects: {
*fetch({ payload }, { call, put }) {
...
const response = yield call(queryUsers);
...
},
}
2.2、Effect 處理異步請求
在處理復雜的異步請求的時候,很容易讓邏輯混亂,陷入嵌套陷阱,所以 Ant Design Pro 的底層基礎框架 dva 使用 effect 的方式來管理同步化異步請求:
effects: {
*fetch({ payload }, { call, put }) {
yield put({
type: 'changeLoading',
payload: true,
});
// 異步請求 1
const response = yield call(queryFakeList, payload);
yield put({
type: 'save',
payload: response,
});
// 異步請求 2
const response2 = yield call(queryFakeList2, payload);
yield put({
type: 'save2',
payload: response2,
});
yield put({
type: 'changeLoading',
payload: false,
});
},
},
通過 generator 和 yield 使得異步調用的邏輯處理跟同步一樣,更多可參看 dva async logic。
2.3、從 mock 直接切換到服務端請求
通常來講只要 mock 的接口和真實的服務端接口保持一致,那么只需要重定向 mock 到對應的服務端接口即可。
// .roadhogrc.mock.js
export default {
'GET /api/(.*)': 'https://your.server.com/api/',
};
這樣你瀏覽器里這樣的接口 http://localhost:8001/api/applications 會被反向代理到 https://your.server.com/api/applications 下。
2.3.1、關閉 mock
關閉 mock 的方法我們推薦采用環境變量,你可以在 package.json 中設置:
"script" : {
"start": "roadhog server",
"start:no-proxy": "cross-env NO_PROXY=true roadhog server"
}
然后在 .roadhogrc.mock.js 中做個判斷即可:
const noProxy = process.env.NO_PROXY === 'true';
...
export default noProxy ? {} : delay(proxy, 1000);
.
