React全家桶+Material-ui構建的管理系統

前言javascript

各大社區中關於react的後臺管理系統已經應有盡有,大部分都是react+antd,偶爾一次看到material-ui這個react UI組件,感受很特別,因而嘗試使用搞一個demo體驗一下,通過不斷細化轉化到目前一個比較完整的項目,特發此文以做記錄,但願能夠幫助更多的開發者。 本文不太適合react初學者,須要對react有必定基礎,大量使用了react-hooks。java

簡介react

一個使用React全家桶(react-router-dom,redux,redux-actions,redux-saga,reselect)+Material-ui構建的後來管理中心。選擇Material-ui的理由:一、默認四大顏色主題隨意切換,主題可繼續擴展,定製;二、內置Grid(柵格)系統,徹底兼容mobile,ipad,pc三端瀏覽器;三、內置icon,可以使用icon-font或者直接svg;四、強大的Table(表格組件)內置搜索功能,可直接導出(下載)表格到本地。五、柔和的動畫體系,加強用戶體驗。放個截圖-_-ios

附錄git

    1. 在線體驗:帳號:admin密碼:123456
    1. 源碼地址:https://github.com/SimpleRoom/walker-admin,以爲有用請戳:star~ 會不斷更新......
    1. 默認使用: create-react-app
    1. 目前分5個頁面:圖表數據,我的資料,員工管理,會員管理,線路設計,酒店預訂
    1. 難點在於redux、redux-actions、redux-saga、reselect這4者如何串聯銜接,來注入管理store。
    1. 目前已經部署上線,後臺相關功能會陸續添加更新!線上地址就不公佈了~~(😁)

工具歸納github

  • 一、redux:管理組件state的容器
  • 二、react-redux:React官方控制React組件與Redux的鏈接容器
  • 三、redux-actions:簡化Redux寫法的工具
  • 四、redux-saga:Redux處理異步數據的中間件
  • 五、reselect:Redux的選擇器工具,精確獲取指定state,減小沒必要要的渲染
  • 六、plop:快速開發工具,自動生成指定模板文件的工具(與react無關,可配置提升開發效率)

功能概況shell

  • 一、路由權限:登陸時接口返回該帳號權限級別,匹配對應的路由routerList注入store
  • 二、數據圖表:熱門景點排名,公司營收圖表情況
  • 三、我的資料:我的信息編輯更新
  • 四、員工管理:員工資料增刪改查,導出
  • 五、會員管理:每個月入會會員統計,即將過時會員統計,會員資料增刪改查,導出
  • 六、線路設計:已有線路的編輯更新,刪除,添加,可隨時更新至對應的app或者小程序
  • 七、酒店預訂:根據線路參團來預訂合適的酒店

部分代碼示例redux

  • 一、如何串聯redux,redux-actions,redux-saga,reselect,如:
//異步獲取github開放的我的信息接口,對應目錄(src/store/modules/common)
// 1.redux-actions
import { createActions } from 'redux-actions'
export const {
  // 獲取github我的信息
  fetchGitInfo,
  setGithubInfo,
} = createActions(
  {
    // 獲取github我的信息
    FETCH_GIT_INFO: (username) => ({ username }),
    SET_GITHUB_INFO: (githubData) => ({ githubData}),
  },
)
export default {}

//2.redux-saga
import axios from 'axios'
import { fork, put, takeEvery } from 'redux-saga/effects'
import {
  // github 我的信息
  fetchGitInfo,
  setGithubInfo,
} from './action'
// 請求github
function* getGithubInfo(action) {
  const { username } = action.payload
  // username爲你的github 用戶名
  const result = yield axios.get(`https://api.github.com/users/${username}`)
  // console.log(action, result, 'saga.....')
  yield put(setGithubInfo(result.data))
}
// 
function* watchCommon() {
  // 請求接口
  yield takeEvery(fetchGitInfo, getGithubInfo)
}
export default [fork(watchCommon)]

//3.reducer
import { handleActions } from 'redux-actions'
import {
  // 暫存github信息
  setGithubInfo,
} from './action'
// 該store的命名空間,可建立多個把store分開管理 
export const namespace = 'common'
export const defaultState = {
  // github我的信息
  githubInfo: {},
}
export const commonReducer = handleActions(
  {
    [setGithubInfo]: (state, action) => {
      const { githubData } = action.payload
      return { ...state, githubData }
    }
  },
  defaultState
)

// 4.reselect
// 從store單獨獲取githubInfo,實際中可能有N多個接口的不一樣數據
export const getGithubData = state => state[namespace].githubData || {}

// 五、組件內部使用
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import { fetchGitInfo } from '../../store/modules/common/action'
import { getGithubData } from '../../store/modules/common/selector'

const mapStateToProps = state => ({
  myGithubInfo: getGithubData(state),
})
const mapDispatchToProps = {
  fetchGitInfo,
}

const MyInfo = (props) => {
  const { myGithubInfo, fetchGitInfo } = props
  // react-hooks新增:可代替componentDidMount和componentDidUpdate
  useEffect(() => {
    if (myGithubInfo && !Object.keys(myGithubInfo).length) {
    // 觸發action,開始請求接口
      fetchGitInfo('wjf444128852')
    }
  }, [myGithubInfo, fetchGitInfo])
  return (
    <div> <p>{myGithubInfo.name}</p> <p>{myGithubInfo.flowers}</p> </div>
  )
}

export default connect(mapStateToProps, mapDispatchToProps)(MyInfo)

複製代碼
  • 三、Material-table,定製thead,配置中文顯示,配置參考(componenst/MaterialTable),支持數據導出功能。
// 1、materialTableConfig.js,可靜態配置共用,可動態經過props根據需展現的數據格式定製
// 1.table-thbody-td的樣式
const bodyCellStyle = {
  fontSize: '0.82rem',
  color: 'rgba(0, 0, 0, 0.87)',
  fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
  fontWeight: 300,
}

// 2.table-thead列數配置,與異步數據格式需一致
export const columnsArr = [
  { title: 'ID', field: 'id', cellStyle: bodyCellStyle },
  { title: '姓名', field: 'name', cellStyle: bodyCellStyle },
  { title: '年齡', field: 'age', cellStyle: bodyCellStyle },
  { title: '加入時間', field: 'joinTime', cellStyle: bodyCellStyle },
  { title: '到期時間', field: 'expiredTime', cellStyle: bodyCellStyle },
  { title: '生日', field: 'birthday', type: 'string', cellStyle: bodyCellStyle },
  {
    title: '出生地',
    field: 'birthCity',
    // birthCity id 
    lookup: { 1: '安徽', 2: '北京', 3: '上海', 4: '深圳', 5: '廣州', 6: '杭州' },
    cellStyle: bodyCellStyle,
  },
]

// 3. 其餘配置,
export const optionsSetting = {
  // thead style
  headerStyle: {
    // backgroundColor: '#66bb6a',
    ...bodyCellStyle,
    fontSize: '1rem',
    color: '#66bb6a',
  },
  rowStyle: {
    backgroundColor: '#EEE',
  },
  //是否須要導出報表CSV文件,按鈕
  exportButton: true,
  //導出報表的名字
  exportFileName: '報表信息',
  // 操做按鈕的位置,定位操做的位置,-1是末尾,默認開頭
  actionsColumnIndex: -1,
  //是否須要開啓分頁
  paging: true,
  // 分頁中每頁數量,異步數據還須要配置total
  pageSize: 10,
}

// 4. table表格語言本地化配置,默認都是英文
export const localizationConfig = {
  header: {
    actions: '操做',
  },
  toolbar: {
    searchTooltip: '搜索',
    searchPlaceholder: '查找指定用戶',
    exportTitle: '導出',
    exportName: '導出到CVS文件',
  },
  body: {
    emptyDataSourceMessage: '當前列表爲空',
    addTooltip: '增長',
    editTooltip: '編輯',
    deleteTooltip: '刪除',
    // 編輯選項提示設置
    editRow: {
      deleteText: '您肯定要刪除該選項嗎?請您三思...',
      saveTooltip: '肯定',
      cancelTooltip: '取消',
    }
  },
  pagination: {
    labelRowsSelect: '條',
    labelDisplayedRows: '{from}-{to} of {count}',
    // labelDisplayedRows: '{count}條',
    firstTooltip: '首頁',
    previousTooltip: '上一頁',
    nextTooltip: '下一頁',
    lastTooltip: '尾頁'
  }
}

//2、組件內使用

import { 
  // columnsArr,
  optionsSetting,
  localizationConfig,
} from './materialTableConfig'

<MaterialTable
 // 表格標題
  title=""
  // thead配置
  columns={columnsConfigArr}
  // 異步data
  data={data}
  // 其餘配置
  options={optionsSetting}
  // 本地化語言顯示設置
  localization={localizationConfig} />

複製代碼

目錄結構axios

plop── 快速建立components和store的模板

     ┌── assets      資源文件
     ├── components  頁面組件
     ├── router      路由配置
     ├── store       state模塊管理中心
src──├── styles      頁面樣式
     ├
     ├── utils       插件和工具
     ├
     ├── views       與路由對應的頁面
     └── index.js    頁面配置入口
     
 
             ┌── Card             面板組件
             ├── CustomButtons    按鈕組件
             ├── CustomInput      輸入框組件
             ├── CustomTabs       公用Tab切換組件
components ──├── Dialog           彈框組件
             ├── Footer           底部footer
             ├── Grid             柵格組件
             ├── HeadNavBar       頭部導航組件
             ├── HotelCard        酒店頁面UI面板
             ├── HotelList        酒店頁面列表UI組件
             ├── Login            登陸組件
             ├── MaterialTable    定製可編輯Table組件
             ├── MuiDatepicker    日期選擇器組件
             ├── MuiTimepicker    時間選擇器組件
             ├── Notifications    自定義提示消息組件
             ├── Snackbar         Material-ui官方消息提示組件
             ├── Table            定製不可編輯的Table組件
             ├── Loading          loading組件
             ├── NotFound         404組件
             ├── ScrollToTopMount 路由切換緩動到頂部組件
             ├── SideBar          側邊欄路由導航
             └── SideTool         右邊工具欄組件
             
             
       ┌── modules         不一樣的state模塊
       ├     ├── account   登陸驗證state
       ├     ├── common    全局公用的state
       ├     └── theme     主題控制state
store──├
       └── indexStore.js   state入口
     
複製代碼

結語小程序

本人目前求職看機會中,歡迎來撩:444128852@qq.com

  • 一、上述中redux的工具使用相對複雜繁瑣,且不適合react初學者!!!!
  • 二、實際中遇到的幾個問題,A:react-loadable不在維護更新,已替換爲@loadable/component;B:react-chartist官方圖表使用的react版本是16.0,已向做者發PR,把componentWillReceiveProps替換爲getDerivedStateFromProps C:打包部署到CDN二級目錄的話,須要針針對路由添加配置,router basename 3 、以上只是實際開發中遇到的筆記總結,如有誤請指出,若有用記得start~
相關文章
相關標籤/搜索