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 相关文章推荐
iis6+javascript Add an Extension File
Jun 13 Javascript
用JQuery 实现AJAX加载XML并解析的脚本
Jul 25 Javascript
JS的千分位算法实现思路
Jul 31 Javascript
Javascript验证上传图片大小[前台处理]
Jul 18 Javascript
JavaScript父子窗体间的调用方法
Mar 31 Javascript
jQuery中ajax错误调试分析
Dec 01 Javascript
使用JavaScript触发过渡效果的方法
Jan 19 Javascript
ReactJS实现表单的单选多选和反选的示例
Oct 13 Javascript
微信小程序Getuserinfo解决方案图解
Aug 24 Javascript
this.$toast() 了解一下?
Apr 18 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
Sep 28 Javascript
jQuery实现增删改查
Dec 22 jQuery
详解开发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
咖啡磨器 如何选购一台适合家用的意式磨豆机
2021/03/05 新手入门
一个取得文件扩展名的函数
2006/10/09 PHP
jq的get传参数在utf-8中乱码问题的解决php版
2008/07/23 PHP
PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)
2014/08/18 PHP
destoon实现调用图文新闻的方法
2014/08/21 PHP
PHP自动生成缩略图函数的源码示例
2019/03/18 PHP
微信推送功能实现方式图文详解
2019/07/12 PHP
Laravel5.5 数据库迁移:创建表与修改表示例
2019/10/23 PHP
FireFox与IE 下js兼容触发click事件的代码
2008/11/20 Javascript
js实现从中间开始往上下展开网页窗口的方法
2015/03/02 Javascript
jQuery支持添加事件的日历特效代码分享(3种样式)
2015/08/24 Javascript
轻松实现Bootstrap图片轮播
2020/04/20 Javascript
基于JavaScript实现的顺序查找算法示例
2017/04/14 Javascript
JS 60秒后重新发送验证码的实例讲解
2017/07/26 Javascript
JS自定义函数实现时间戳转换成date的方法示例
2017/08/27 Javascript
AngularJS实现自定义指令及指令配置项的方法
2017/11/20 Javascript
vue 使用ref 让父组件调用子组件的方法
2018/02/08 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
2018/10/09 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
用Python制作检测Linux运行信息的工具的教程
2015/04/01 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
2018/03/04 Python
Python3爬虫学习入门教程
2018/12/11 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
2018/12/15 Python
用python 实现在不确定行数情况下多行输入方法
2019/01/28 Python
python 如何停止一个死循环的线程
2020/11/24 Python
IE矩阵Matrix滤镜旋转与缩放及如何结合transform
2012/11/29 HTML / CSS
AVI-8手表美国官方商店:AVI-8 USA
2019/04/10 全球购物
戴尔荷兰官方网站:Dell荷兰
2020/10/04 全球购物
优秀驾驶员先进事迹材料
2014/05/04 职场文书
婚庆公司开业主持词
2015/06/30 职场文书
男方家长婚礼致辞
2015/07/27 职场文书
学校安全管理制度
2015/08/06 职场文书
六五普法先进个人主要事迹材料
2015/11/03 职场文书
JVM钩子函数的使用场景详解
2021/08/23 Java/Android
MySQL RC事务隔离的实现
2022/03/31 MySQL
python热力图实现的完整实例
2022/06/25 Python