一、概述
原文地址: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);
.