前言
各大社区中关于react的后台管理系统已经应有尽有,大部分都是react+antd,偶尔一次看到material-ui这个react UI组件,感受很特别,因而尝试使用搞一个demo体验一下,通过不断细化转化到目前一个比较完整的项目,特发此文以做记录,但愿能够帮助更多的开发者。
本文不太适合react初学者,须要对react有必定基础,大量使用了react-hooks。javascript
简介
一个使用React全家桶(react-router-dom,redux,redux-actions,redux-saga,reselect)+Material-ui构建的后来管理中心。选择Material-ui的理由:一、默认四大颜色主题随意切换,主题可继续扩展,定制;二、内置Grid(栅格)系统,彻底兼容mobile,ipad,pc三端浏览器;三、内置icon,可以使用icon-font或者直接svg;四、强大的Table(表格组件)内置搜索功能,可直接导出(下载)表格到本地。五、柔和的动画体系,加强用户体验。放个截图-_-java
附录
admin
密码:123456
工具归纳
功能概况
部分代码示例
//异步获取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)
// 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} />
目录结构
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.comreact
C:打包部署到CDN二级目录的话,须要针针对路由添加配置,router basename
3 、以上只是实际开发中遇到的笔记总结,如有误请指出,若有用记得start~ios