dva-boot-admin 是一個用React開發的一個企業級中後臺管理UI,包含常用的業務,組件,及數據流轉方案,前後端分離的開發方式,按業務劃分的目錄結構,可以大大提高我們的開發效率
下面是整體的介紹,感興趣的同學可以去官網詳加了解。
功能
- 封裝了dva框架的數據流轉,簡單的請求可以不用在model和service中定義
- 封裝了數據模模擬,可以獨立於後臺開發前臺功能
- 封裝了分頁請求,簡化並規範了分頁邏輯
- 封裝了fetch請求,適應與後臺多種交互請求, body參數 parameter參數 path參數,動態請求頭,請求前後攔截
- 擴展了antd寫了許多實用的UI,通過一個配置生成即可生成,後臺CRUD三件套
- 按業務模塊劃分的目錄結構,儘量做到最小耦合
- 一些常用的小部件用法
- 許多精心設計的頁面及交互場景
- dva-boot腳手架封裝的功能
- 全局異常處理,全局請求攔截,公共配置提取
目錄結構
.
├── 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