React & Create-React-App & DVA 的後臺管理UI

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章