react配合antd组件实现的管理系统示例代码


Posted in Javascript onApril 24, 2018

前言:此文需要有一定react,redux基础,具体学习资料请科学上网。

使用create-react-app脚手架

开发前反思

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 /> : <div>加载中...</div>
  }}
 </Bundle>

2. 全局loading

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

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

3. 配置路由对象

项目布局如下

react配合antd组件实现的管理系统示例代码

本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 (
    <div> 
      {this.props.children}
    </div>
  )
}
// 本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:base64:5]'
      }
    }, {
      loader: require.resolve('postcss-loader'),
      options: {
        // Necessary for external CSS imports to work
        // https://github.com/facebookincubator/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适合大型项目,多人协作

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS获取子窗口中返回的数据实现方法
May 28 Javascript
深入理解javascript作用域第二篇之词法作用域和动态作用域
Jul 24 Javascript
js 获取当前web应用的上下文路径实现方法
Aug 19 Javascript
Angular 应用技巧总结
Sep 14 Javascript
9个让JavaScript调试更简单的Console命令
Nov 14 Javascript
jQuery实现简易的输入框字数计数功能示例
Jan 16 Javascript
JavaScript贪吃蛇小组件实例代码
Aug 20 Javascript
总结js中的一些兼容性易错的问题
Dec 18 Javascript
JS实现自定义弹窗功能
Aug 08 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
Jan 08 Javascript
监听element-ui table滚动事件的方法
Mar 26 Javascript
JavaScript TAB栏切换效果的示例
Nov 05 Javascript
详解开发react应用最好用的脚手架 create-react-app
Apr 24 #Javascript
vue webpack实用技巧总结
Apr 24 #Javascript
浅谈vue中.vue文件解析流程
Apr 24 #Javascript
vue-cli2.9.3 详细教程
Apr 23 #Javascript
vue.js数据绑定操作详解
Apr 23 #Javascript
jQuery+ajax实现动态添加表格tr td功能示例
Apr 23 #jQuery
再谈Angular4 脏值检测(性能优化)
Apr 23 #Javascript
You might like
PHP调用MySQL的存储过程的实现代码
2008/08/12 PHP
php函数与传递参数实例分析
2014/11/15 PHP
php+xml结合Ajax实现点赞功能完整实例
2015/01/30 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
2019/09/19 PHP
JavaScript RegExp方法获取地址栏参数(面向对象)
2009/03/10 Javascript
js实现点击后将文字或图片复制到剪贴板的方法
2014/08/04 Javascript
简单学习JavaScript中的for语句循环结构
2015/11/10 Javascript
jquery中checkbox使用方法简单实例演示
2015/11/24 Javascript
JS DOM实现鼠标滑动图片效果
2020/09/17 Javascript
js跨域资源共享 基础篇
2016/07/02 Javascript
Node.js  REPL (交互式解释器)实例详解
2017/08/06 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
2018/07/16 Javascript
解决vue打包css文件中背景图片的路径问题
2018/09/03 Javascript
在小程序/mpvue中使用flyio发起网络请求的方法
2018/09/13 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
angular8和ngrx8结合使用的步骤介绍
2019/12/01 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
python每次处理固定个数的字符的方法总结
2013/01/29 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
python基于http下载视频或音频
2018/06/20 Python
Python3+PyInstall+Sciter解决报错缺少dll、html等文件问题
2019/07/15 Python
pytorch常见的Tensor类型详解
2020/01/15 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
python中pow函数用法及功能说明
2020/12/04 Python
利用CSS的Sass预处理器(框架)来制作居中效果
2016/03/10 HTML / CSS
H5 meta小结(前端必看篇)
2016/08/24 HTML / CSS
HTML5页面音视频在微信和app下自动播放的实现方法
2016/10/20 HTML / CSS
建筑工程实习自我鉴定
2013/09/19 职场文书
小学生打架检讨书
2014/01/26 职场文书
HR求职自荐信范文
2014/06/21 职场文书
倡议书的写法
2014/08/30 职场文书
缓刑人员思想汇报500字
2014/09/12 职场文书
公安机关纪律作风整顿个人剖析材料材料
2014/10/10 职场文书
经营场所证明范本
2015/06/19 职场文书
如何开启Apache,Nginx和IIS服务器的GZIP压缩功能
2022/04/29 Servers