基於react 16 dva 2 的後臺管理UI
dva-boot-admin 是一個用React開發的一個企業級中後臺管理UI,包含常用的業務,元件,及資料流轉方案,前後端分離的開發方式,按業務劃分的目錄結構,可以大大提高我們的開發效率
下面是整體的介紹,感興趣的同學可以去官網詳加了解。
功能
- 封裝了dva框架的資料流轉,簡單的請求可以不用在model和service中定義
- 封裝了資料模模擬,可以獨立於後臺開發前臺功能
- 封裝了分頁請求,簡化並規範了分頁邏輯
- 封裝了fetch請求,適應與後臺多種互動請求, body引數 parameter引數 path引數,動態請求頭,請求前後攔截
- 擴充套件了antd寫了許多實用的UI,通過一個配置生成即可生成,後臺CRUD三件套
- 按業務模組劃分的目錄結構,儘量做到最小耦合
- 一些常用的小部件用法
- 許多精心設計的頁面及互動場景
- 全域性異常處理,全域性請求攔截,公共配置提取
目錄結構
.
├── public # 不參與編譯的資原始檔
├── src # 主程式目錄
│ ├── index.js # 程式啟動和渲染入口檔案
│ ├── components # 全域性公共元件
│ ├── layouts # 頁面結構元件
│ │ ├── BasicLayout # 基本佈局
│ │ └── OtherLayout # 佈局元件根據具體功能調整,在路由配置中引用
│ ├── routes # 動態路由目錄(每個功能一個資料夾的MVC結構)
│ │ ├── index.js # 路由配置檔案
│ │ ├── Home # 功能模組
│ │ │ ├── index.js # 路由配置檔案
│ │ │ ├── assets # 單獨屬於這個模組的靜態資原始檔
│ │ │ ├── components # 頁面元件
│ │ │ ├── model # dva model
│ │ │ ├── service # dva service
│ │ │ └── routes ** # 子路由(目錄結構與父級相同)
│ │ └── Login # 功能模組
│ │ ├── index.js # 路由配置檔案
│ │ ├── assets # 單獨屬於這個模組的靜態資原始檔
│ │ ├── components # 頁面元件
│ │ ├── model # dva model
│ │ ├── service # dva service
│ │ └── routes ** # 子路由(目錄結構與父級相同)
│ ├── utils # 工具類
│ └── assets # 資原始檔
│ ├── fonts # 字型 & 字型圖示
│ ├── images # 圖片
│ └── styles # 全域性樣式
常用方法
modelEnhance
modelEnhance是對dva model層的簡單包裝函式,有時候我們只是想要簡單的fetch一下,從服務端獲取資料進行展示,之前可能要專門在model中寫一些effects和reducers,在service中定義請求函式,如果用modelEnhance包裝一下的話可以簡寫成下面的形式
// src/routes/UserInfo/model/index.js
import modelEnhance from '@/utils/modelEnhance';
// 就是普通的dva model傳入modelEnhance即可,不用定義其它變數
export default modelEnhance({
namespace: 'userInfo',
});
// src/routes/UserInfo/components/index.js
// 在元件中直接發出一個型別為`@request`的action,
// 結果會存入userInfo對應的state中,使用的key為`valueField`的值
this.props.dispatch({
type: 'userInfo/@request',
payload: {
url: 'http://httpbin.org/get',
valueField: 'httpbin',
method: 'GET'
}
});
// 同時請求兩個
this.props.dispatch({
type: 'userInfo/@request',
payload: [{
url: 'http://httpbin.org/get',
valueField: 'httpbin',
method: 'GET'
}, {
url: 'http://httpbin.org/post',
valueField: 'httpbin'
}]
});
// 結合分頁助手使用,查詢第1頁10條資料
this.props.dispatch({
type: 'userInfo/@request',
payload: {
valueField: 'pageData',
url: '/api/userInfo/getList',
pageInfo: pageData.startPage(1, 10),
}
});
exception
全域性異常處理,我們可以在src/config.js的exceptiion
中處理通用異常,這裡共實就是dva的onError方法的入口,我們一般處理如登入超時,使用者沒有許可權,或另種請求異常等,建議大家不同的異常可以單獨包裝成一個異常類進行分類處理,這樣更容易維護以及除錯。
config
工程的配置檔案
fetch mock
模擬服務端響應資料,常常用在前後端分離的專案中,我們在開發新功能的時候,前後端是不同步的,這時我們就會建立一些資料原型,協商好後這時後端就可以開始開發,而我們可以繼續使用模擬資料,只有當後端完成這個介面並測試通過後,二者才會被整合。這之後如果後端因為某些原因服務不可用時,我們也會很方便的切換回模擬資料,這樣不會因為後端的問題而影響後續的開發。
要新建一些模擬資料只要在__mocks__
資料夾中,建立一個檔案,並在資料夾中的index.js
中進行宣告,一些例子可以直接在資料夾下面找到。
所有的模擬資料是在開發環境中執行的,當您打包成生產環境的包時,會自動遮蔽所有模擬資料介面。
// 例子: /src/__mocks__/userInfo.js
/**
* 模擬請求資料
* @param {FetchMock} fetchMock 當現有條件不滿足時,可以使用fetchMock來進行擴充套件
* @param {number} delay 增加延遲時間 ms
* @param {function} mock 使用mock生成資料,例如:
mock({
'string|1-10': '★' // 生成最少1顆,最多10顆星字元
})
// {'string': '★★★★★★'}
*/
export default ({fetchMock, delay, mock}) => {
// 如果現有擴充套件不滿足需求,可以直接使用fetchMock方法
// fetchMock.mock(/httpbin.org\/post/, {/* response */}, {/* options */});
return {
// 一般用法
'GET /api/getUserInfo': {
name: 'jonn'
},
// 省略 method, 模擬真實請求延遲效果
'/api/getUsers': delay([
{ name: 'jonn' },
{ name: 'weiq' },
]),
// 表格帶分頁
'/api/userInfo/getList': delay(mock({
'pageNum|+1': 1, // 遞增加1
'pageSize': 10,
'size': 10,
'total': 500,
'totalPages': 50,
'list|10': [{
'name': '@cname', // 中文名稱
'age|1-100': 100, // 100以內隨機整數
'birthday': '@date("yyyy-MM-dd")', // 日期
'city': '@city(true)', // 中國城市
'phone': /^1[385][1-9]\d{8}/ // 手機號
}],
})),
// 表格帶分頁, 寫成函式形式可以使用請求引數,
// 更真實的模擬後端資料處理業務
'/api/userInfo/getList1': (options) => {
const body = JSON.parse(options.body);
const pageNum = body.pageNum;
const idbase = (pageNum - 1) * 10 + 1;
return toSuccess(mock({
'pageNum': pageNum,
'pageSize': 10,
'size': 10,
'total': 100,
'totalPages': 10,
'list|10': [{
'id|+1': idbase,
'name': '@cname', // 中文名稱
'age|1-100': 100, // 100以內隨機整數
'birthday': '@date("yyyy-MM-dd")', // 日期
'city': '@city(true)', // 中國城市
'phone': /^1[385][1-9]\d{8}/ // 手機號
}],
}), 400)
}
}
}
page helper (簡單分頁)
在做後臺系統的時候,做的最多的可能就是對錶格的增、刪、改、查,這時我們的頁面一般是這樣的,上面是對錶格條件的檢索框,中間是我們的資料表格,表格下面是分頁元件,還會有新增,修改時用到表單元件
拿對錶格資料進行檢索這個場景來說,在搜尋框(可能有多個)輸入條件,點選搜尋,檢索到結果(可能非常多),我們會點選下面的分頁元件進行翻頁,翻頁時我們就得帶著之前的檢索條件,我們會在傳送請求前手動合併這些條件,並計算下一頁的頁數等
而PageHelper
分頁助手就是為了簡化我們的程式碼量的,如使用PageHelper.create()
這個方法會為我們自動生成分頁物件
// model.js
state: {
pageData: PageHelper.create()
}
這時我們可以在元件中使用這個物件很方便的進行分頁,及檢索,並且支援鏈式寫法,所有條件會自動進行合併,如:
// components
const {pageData} = this.props;
// 查詢第1頁,每頁10條,並且name為jonn的資料
pageData.startPage(1, 10).filter({name: 'jonn'}).filter(...).sortBy(...);
// 查詢下一頁,並且會帶著之前的查詢條件
pageData.nextPage();
我們還可以結合modelEnhance
來使用分頁,更多用法會在例子中進行說明。
cmn-utils
腳手架使用了cmn-utils做為工具庫,這裡面提供了請求、儲存、事件等許多實用方法
開發&執行
$ git clone https://github.com/LANIF-UI/dva-boot.git
$ cd dva-boot
$ yarn
$ yarn start
// 或使用npm
$ npm install
$ npm start