视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
react+antd做一个后台管理系统
2020-11-27 19:40:47 责编:小采
文档
这次给大家带来react+antd做一个后台管理系统,react+antd做一个后台管理系统的注意事项有哪些,下面就是实战案例,一起来看一下。

使用create-react-app脚手架

具体基础配置请参考

配合antd组件实现的管理系统demo,线上地址

开发前反思

1. 按需加载

webpack的 import 动态加载的模块的函数,import(参数),参数为模块地址。

注意: import 后会返回一个promise对象。

import('/components/chart').then(mud => {
 dosomething(mod)
});

本demo构建了异步加载组件Bundle,具体代码请见

class Bundle extends Component {
 constructor(props) {
 super(props);
 this.state = {
 mod: null
 };
 }
 unmount = false
 componentDidMount = () => {
 // 加载组件时,打开全局loading
 this.props.dispatch(loading(true))
 this.load(this.props)
 }
 componentWillUnmount = () => {
 this.unmount = true
 }
 
 componentWillReceiveProps(nextProps) {
 if (nextProps.load !== this.props.load) {
 this.load(nextProps)
 }
 }
 load(props) {
 if (this.state.mod) {
 return true
 }
 //注意这里,使用Promise对象; mod.default导出默认
 props.load().then((mod) => {
 if (this.unmount) {
 // 离开组件时,不异步执行setState
 this.props.dispatch(loading(false))
 return false
 }
 this.setState({
 mod: mod.default ? mod.default : mod
 }, _ => {
 // 组件加载完毕,关闭loading
 this.props.dispatch(loading(false))
 });
 });
 }
 render() {
 return this.state.mod ? this.props.children(this.state.mod) : null;
 }
}

具体使用

<Bundle load={() => import('路径')}>
 {Comp => {
 return Comp ? <Comp /> : <p>加载中...</p>
 }}
 </Bundle>

2. 全局loading

配合redux,dispatch => reducer更新 => mapstate更新,在根组件进行loading的渲染

详细请见本demo地址 src/routers/router.js——render函数

3. 配置路由对象

项目布局如下

本demo使用的是router4,官方文档演示为单行Route(如vue种的router),未有统一配置对象。 管理系统基本围绕着content进行业务开发,构建通用配置有助于开发 构建router.config.js

const routers = [
 {
 menuName: '主页',
 menuIco: 'home',
 component: 'home/home.js', // 主页
 path: '/admin/home' // 主页
 },
 {
 menuName: '用户',
 menuIco: 'user',
 children: [
 {
 menuName: '用户列表',
 component: 'user/list.js', // 主页
 path: '/admin/user/list' // 主页
 }
 ]
 },
 {
 menuName: '多级菜单',
 menuIco: 'setting',
 children: [
 {
 menuName: '多级菜单2',
 children: [
 {
 menuName: '菜单',
 component: 'user/list.js', // 主页
 path: '/admin/user/list3' // 主页
 }
 ]
 }
 ]
 },
 {
 menuName: '关于我',
 menuIco: 'smile-o',
 component: 'about/about.js', // 主页
 path: '/admin/about' // 主页
 }
]

实现思路,最外层布局为Admin,content被Admin包裹,那么可以利用 this.props.children ,把内容打入content中。(利用bundle组件异步加载后塞入组件进行渲染)

<Admin>
 <Content { ...this.props } breadcrumb={this.state.breadcrumb}>
 {this.props.children}
 </Content>
</Admin>
// Content组件内部
render() {
 return (
 <p> 
 {this.props.children}
 </p>
 )
}
// 本demo实现,详见src/routers/router.js
<Route
 path="/admin"
 render={item => (
 <Admin {...item} { ...this.props }>
 {initRouters.map(el => this.deepItem(el, { ...this.props, ...item}))}
 </Admin>
 )}
/>

4. 配置通用reducer

多人配合开发,一些业务场景的组件需要状提升(不理解状态提升的同学,请科学上网)

import otherReducers from './otherReducers'
const App = combineReducers({
 rootReducers,
 ...otherReducers // 其他需要增加的reducers
})

5. 登陆验证

利用 withRouter 函数,页面进行路由跳转时触发该函数

const newWithRouter = withRouter(props => {
 // ....
})

若未登录,则返回

return <Redirect to="/login" />

6. 路由拦截

同上,根据路由配置与权限,返回相应的菜单或屏蔽

return <Redirect to={其他} />

7 其他配置

7-1. 自定义样式

// 修改webpack.config.dev.js 和 webpack.config-prod.js 配置文件
{
 test: /\.(css|less)$/,
 // 匹配src的都自动加载css-module
 include: [/src/],
 exclude: [/theme/],
 use: [
 require.resolve('style-loader'), {
 loader: require.resolve('css-loader'),
 options: {
 importLoaders: 1,
 modules: true, // 新增对css modules的支持
 localIdentName: '[path]___[name]__[local]___[hash:base:5]'
 }
 }, {
 loader: require.resolve('postcss-loader'),
 options: {
 // Necessary for external CSS imports to work
 // https://github.com/incubator/create-react-app/issues/2677
 ident: 'postcss',
 plugins: () => [
 require('postcss-flexbugs-fixes'),
 autoprefixer({
 browsers: [
 '>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9', // React doesn't support IE8 anyway
 ],
 flexbox: 'no-2009'
 })
 ]
 }
 }, {
 loader: require.resolve('less-loader') // compiles Less to CSS
 }
 ]
}, {
 // 不匹配node_modules,theme的都不能自动加载css-module
 test: /\.(css|less)$/,
 include: [/node_modules/,/theme/],
 use: [
 {
 loader: "style-loader"
 }, {
 loader: "css-loader",
 options: {
 importLoaders: 1
 }
 }, {
 loader: require.resolve('less-loader') // compiles Less to CSS
 }
 ]
},

使用: 在App.js中直接导入

import './assets/theme/App.less'

7-2. 热更新

步骤一:

// 安装react-hot-loader 
npm install --save-dev react-hot-loader

步骤二:

在webpack.config.js 的 entry 值里加上 react-hot-loader/patch

步骤三:

webpackDevServer.config.js中hot设置为true

步骤四: 在webpack.config.dev.js中在babel-loader中plugins加入react-hot-loader/babel

{
 test: /\.(js|jsx|mjs)$/,
 include: paths.appSrc,
 loader: require.resolve('babel-loader'),
 options: {
 // This is a feature of `babel-loader` for webpack (not Babel itself). It
 // enables caching results in ./node_modules/.cache/babel-loader/ directory for
 // faster rebuilds.
 cacheDirectory: true,
 plugins: [
 'react-hot-loader/babel'
 ]
 }
},

步骤五:

重写index.js,App挂载

import { AppContainer } from 'react-hot-loader'
const render = Component => {
 ReactDOM.render(
 <AppContainer>
 <Component></Component>
 </AppContainer>,
 document.getElementById('root')
 )
}
render(App)
if(module.hot) {
 module.hot.accept('./App',() => {
 render(App);
 });
}

7-3. 本地浏览

直接在package.json中 加入

homepage:'.'

后记:使用react与vue的感悟

react是函数式编程,代码难度、学习曲度、装逼指数,社区生态多样性相比vue更高一点。

vue提供了大量的指令降低了开发难度,详细完善的文档,上手更快。

react提供较少的api,相比vue的指令,业务场景的功能需要自己实现,难度更高一点

vue适合中小型项目,单兵、少量人员配合快速开发

react适合大型项目,多人协作

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

配置打包文件路径出错怎样解决

怎样做出点击标题文字切换字体效果

下载本文
显示全文
专题