【后台管理系統】—— Ant Design Pro入門學習&項目實踐筆記(一)


前言:最近在做公司的一個后台管理系統項目,前端是用React的Ant Design Pro 2.0 ,可以開箱即用,底層使用了dva和umi代替了redux和umi,使用起來更方便了。

第一次用Ant Design Pro,這里為進一步學習做一個梳理便於自己和大家翻閱(O(∩_∩)O~


一、項目准備

  • 官網https://pro.ant.design/docs/getting-started-cn
  • 官方工作台https://preview.pro.ant.design/dashboard/workplace
  • 本地環境:需要安裝 node 和 git。我們的技術棧基於 ES2015+ReactUmiJSdvag2 和 antd
  • 安裝
    $ git clone --depth=1 https://github.com/ant-design/ant-design-pro.git my-project
    $ cd my-project  
  • 目錄結構:已自動生成一個完整的框架
    ├── config                   # umi 配置,包含路由,構建等配置
    ├── mock                     # 本地模擬數據
    ├── public
    │   └── favicon.png          # Favicon
    ├── src
    │   ├── assets               # 本地靜態資源
    │   ├── components           # 業務通用組件
    │   ├── e2e                  # 集成測試用例
    │   ├── layouts              # 通用布局
    │   ├── models               # 全局 dva model
    │   ├── pages                # 業務頁面入口和常用模板
    │   ├── services             # 后台接口服務
    │   ├── utils                # 工具庫
    │   ├── locales              # 國際化資源
    │   ├── global.less          # 全局樣式
    │   └── global.js            # 全局 JS
    ├── tests                    # 測試工具
    ├── README.md
    └── package.json  
  • 本地開發:安裝依賴
    $ npm install
    
    $ npm start  
  • 啟動完成:會自動打開瀏覽器訪問 http://localhost:8000

     

二、布局

  • 抽離出的通用布局:放在 layouts 目錄中
  1. BasicLayout:基礎頁面布局,包含了頭部導航,側邊欄和通知欄
  2. UserLayout:抽離出用於登陸注冊頁面的通用布局
  3. BlankLayout:空白的布局
  • 布局與路由系統結合:Ant Design Pro 的路由使用了 Umi 的路由方案,將配置信息統一抽離到 config/router.config.js 下
  1. 映射路由與頁面布局之間的關系
    module.exports = [{
      path: '/',
      component: '../layouts/BasicLayout',  // 指定以下頁面的布局
      routes: [
        // dashboard
        { path: '/', redirect: '/dashboard/analysis' },
        {
          path: '/dashboard',
          name: 'dashboard',
          icon: 'dashboard',
          routes: [
            { path: '/dashboard/analysis', name: 'analysis', component: './Dashboard/Analysis' },
            { path: '/dashboard/monitor', name: 'monitor', component: './Dashboard/Monitor' },
            { path: '/dashboard/workplace', name: 'workplace', component: './Dashboard/Workplace' },
          ],
        },
      ],
    }]  
  2. 更多的Umi路由配置方式 :Umi 配置式路由
  3. Pro擴展配置:在 router.config.js 擴展了一些關於 pro 全局菜單的配置
    {
      name: 'dashboard',  //當前路由在菜單和面包屑中的名稱,國際化配置的key
      icon: 'dashboard',  //當前路由在菜單下的圖標名
      hideInMenu: true,   //當前路由在菜單中不展現,默認 false
      hideChildrenInMenu: true,  //當前路由的子級在菜單中不展現,默認 false
      hideInBreadcrumb: true,    //當前路由在面包屑中不展現,默認 false
      authority: ['admin'],      //允許展示的權限,不設則都可見
    }  
  • 布局組件:除了 Pro 里的內建布局以外,在一些頁面中需要進行布局,可以使用 AntD 的兩套布局組件工具:Layout 和 Grid

  1. Grid 組件:柵格布局按比例划分頁面,具有彈性布局的特點,能設置間距、支持響應式的比例設置和flex模式 (Grid

  2. Layout 組件:輔助頁面框架級別的布局設計,只需要填空就可以開發規范專業的頁面整體布局(Layout

  3.  注意:通常會把抽象出來的布局組件,放到跟 pages、 components 平行的 layouts 文件夾中方便管理 

 

三、路由和菜單 

  • 基本結構
  1. 路由管理:通過約定的語法根據在 router.config.js 中配置路由
  2. 菜單生成:根據路由配置來生成菜單。菜單項名稱,嵌套路徑與路由高度耦合
  3. 面包屑:組件 PageHeader 中內置的面包屑也可由腳手架提供的配置信息自動生成
  • 路由
  1. 目前腳手架中所有的路由都通過 router.config.js 來統一管理
  2. 在 umi 的配置中我們增加了一些參數,來輔助生成菜單,如上↑(Pro擴展配置)(更多:umi#路由)
  • 菜單
  1. 菜單根據 router.config.js 生成,具體邏輯在 src/models/menu.js 中的 formatter 方法實現。
  2. 注意:如果項目不需要菜單,可直接在 BasicLayout 中刪除 SiderMenu 組件的掛載。並在 src/layouts/BasicLayout 中設置 const MenuData = []
  • 從服務器請求菜單
  1. 只需在 models/menu 中發起 http 請求(*getMenuData),menuData 是一個 json 數組。只需服務器返回類似格式的 json 即可。
  2. 注意:path 必須要在 routre.config.js 中定義。(約定式路由不需要,只需頁面真實有效即可)
  • 面包屑
  1. 面包屑由 PageHeaderWrapper 實現,MenuContext 將 根據 MenuData 生成的 breadcrumbNameMap 通過 props 傳遞給了 PageHeader。
  2. 自定義的面包屑:可以通過修改傳入的 breadcrumbNameMap 來解決。
  3. 菜單跳轉到外部地址:直接將完整 url 填入 path 中,框架會自動處理。
  • 帶參數的路由
  1. 支持,但需要自己寫
    { 
      path: '/dashboard/:page',
      hideInMenu:true,
      name: 'analysis',
      component: './Dashboard/Analysis', 
    },  
  2. 路由跳轉:2種方法,umi的router.push()和<Link  />
    import router from 'umi/router';
    
    router.push('/dashboard/anyParams')
    
    //or
    
    import Link from 'umi/link';
    
    <Link to="/dashboard/anyParams">go</Link>
  3. 在路由組件中,可以通過this.props.match.params 來獲得路由參數 

 

四、新增頁面和業務組件

  • 新增 js、less 文件:在 src/pages 下新建頁面的 js 及 less 文件,多個頁面可以新建文件夾放置
  • 將文件加入菜單和路由:按照上面↑方式加入,訪問 http://localhost:8000/#/new 即可看到新增頁面
  • 新增 model 和 service:如果需要用到 dva 中的數據流,要在 src/models src/services 中建立相應的 model 和 service
  • 新增業務組件:在 src/components 下新建一個以組件名命名的文件夾,注意首字母大寫,命名盡量體現組件的功能

 

五、樣式

  • Less: Ant Design Pro 默認使用 less 作為樣式語言

  • CSS Modules: 模塊化引入css文件

    // example.js
    import styles from './example.less';
    
    export default ({ title }) => <div className={styles.title}>{title}</div>;
    
    // example.less
    .title {
      color: @heading-color;
      font-weight: 600;
      margin-bottom: 16px;
    }
    
  1. js 文件的改變就是在設置 className 時,用一個對象屬性取代了原來的字符串,屬性名跟 less 文件中對應的類名相同,對象從 less 文件中引入

  2. .title只會在本文件中生效,要定義全局樣式,使用:global
    /* 定義全局樣式 */
    :global(.text) {
      font-size: 16px;
    }
    
    /* 定義多個全局樣式 */
    :global {
      .footer {
        color: #ccc;
      }
      .sider {
        background: #ebebeb;
      }
    }  
  • 樣式文件類別
  1. src/index.less:全局樣式文件(因為 antd 會自帶一些全局設置,如字號,顏色,行高等,所以這里只需要關注自己的個性化需求即可,不用進行大量的 reset)
  2. src/utils/utils.less:工具函數供調用,如.clearfox清除浮動

  3. src/layouts/BasicLayout.less: 基本布局樣式(如項目需要使用其他布局,也建議將布局相關的 js 和 less 放在這里src/layouts

  4. src/routes/Dashborad/Monitor.less:具體頁面相關的樣式,里面的內容僅和本頁面的內容相關

  5. 組件級樣式:重復使用的組件,其相關的樣式也應該提煉出來放在組件中,而不是混淆在頁面里

  6. 內聯樣式: style={{ ... }}
  • 覆蓋組件樣式

  1. 被覆蓋的類名必須放到 :global 中,此時覆蓋是全局性的

  2. 為了防止對其他 同類 組件造成影響,所以需要包裹額外的 className 限制樣式的生效范圍 

 

六、和服務端進行交互

  • DVA 是基於 redux、redux-saga 和 react-router 的輕量級前端框架及最佳實踐沉淀(model 是 DVA 中最重要的概念)
  1. namespace:model 的命名空間,只能用字符串。一個大型應用可能包含多個 model,通過namespace區分。

  2. state:當前 model 狀態的初始值,表示當前狀態。

  3. reducers:用於處理同步操作,可以修改 state,由 action 觸發。reducer 是一個純函數,它接受當前的 state 及一個數據體(payload)作為入參,返回一個新的 state。

  4. effects:用於處理異步操作(例如:與服務端交互)和業務邏輯,也是由 action 觸發。但是,它不可以修改 state,要通過觸發 action 調用 reducer 實現對 state 的間接操作。 

  5. action:是 reducers 及 effects 的觸發器,一般是一個對象,形如{ type: ‘add’, payload: todo },通過 type 屬性可以匹配到具體某個 reducer 或者 effect,payload 屬性則是數據體,用於傳送給 reducer 或 effect。

     

  • 使用mock模擬數據
  1. 在根目錄下新建mock文件夾

  2. 新建 mock/xxx.js

    // 代碼中會兼容本地 service mock 以及部署站點的靜態數據
    export default {
        // 支持值為 Object 和 Array
        // GET POST 可省略
        'POST /api/register': (req, res) => {
             res.send({ status: 'ok', currentAuthority: 'user' });
        }
    }  
  3. mock文件夾在umi中,會自動引入使用,可以新建多個mock文件。會根據請求路徑對應攔截  

  • 在 model 中請求服務端數據
  1. 代理請求:跨域問題

  2. 在配置文件config/config.js添加
    proxy: {
        '/login': {
          target: 'http://192.168.1.106:9099', //代理請求的服務器地址
          changeOrigin: true,
          pathRewrite: { '^/login/': '' }
        },
    }  
  3. 代理請求成功,顯示的請求地址不會改變,仍為 http://localhost:8000
  4. 如果沒做其他處理,使用mock數據時,需要關閉proxy代碼

 

七、構建和發布

  • 構建
    npm run build  
  • 前端路由與服務端的結合
  1. Ant Design Pro 使用的 Umi 支持兩種路由方式:browserHistory 和 hashHistory
  2. 可以在 config/config.js 中配置選擇用哪種方式:
    export default {
      history: 'hash', // 默認是 browser
    }  
  3. browserHistory路由方式:需要服務器做好處理 URL 的准備,否則在刷新路由后,請求會異常內容不能正常顯示
  4. hashHistory路由方式:瀏覽器訪問到的始終都是根目錄下 index.html,在來回刷新路由后,請求正常內容可以正常顯示

 

八、學習推薦  

 

參考資料 


注:轉載請注明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM