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 相关文章推荐
JavaScript中的稀疏数组与密集数组[译]
Sep 17 Javascript
JS 获取浏览器和屏幕宽高等信息的实现思路及代码
Jul 31 Javascript
jquery插件pagination实现无刷新ajax分页
Sep 30 Javascript
JS实现的适合做faq或menu滑动效果示例
Nov 17 Javascript
js实现文字向上轮播功能
Jan 13 Javascript
Angular.js ng-file-upload结合springMVC的使用教程
Jul 10 Javascript
微信小程序实现人脸识别
May 25 Javascript
JavaScript模板引擎实现原理实例详解
Dec 14 Javascript
vue实现购物车抛物线小球动画效果的方法详解
Feb 13 Javascript
p5.js实现故宫橘猫赏秋图动画
Oct 23 Javascript
vue cli3 配置proxy代理无效的解决
Oct 30 Javascript
js实现随机圆与矩形功能
Oct 29 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将字符串转化成date存入数据库的两种方式
2014/04/28 PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
2014/07/01 PHP
PHP解码unicode编码的中文字符代码分享
2014/08/13 PHP
PHP原生函数一定好吗?
2014/12/08 PHP
分享php代码将360浏览器导出的favdb的sqlite数据库文件转换为html
2015/12/09 PHP
PHP实现的简单分页类及用法示例
2016/05/06 PHP
php中static 静态变量和普通变量的区别
2016/12/01 PHP
php实现简单的权限管理的示例代码
2017/08/25 PHP
Jquery实现视频播放页面的关灯开灯效果
2013/05/27 Javascript
查找Oracle高消耗语句的方法
2014/03/22 Javascript
浅谈javascript中return语句
2015/07/15 Javascript
javascript实现起伏的水波背景效果
2016/05/16 Javascript
当jquery ajax遇上401请求的解决方法
2016/05/19 Javascript
BootStrap下拉框在firefox浏览器界面不友好的解决方案
2016/08/18 Javascript
微信小程序图片自适应支持多图实例详解
2017/06/21 Javascript
elementUI table表格动态合并的示例代码
2019/05/15 Javascript
详解Vite的新体验
2021/02/22 Javascript
Python 除法小技巧
2008/09/06 Python
python正则匹配查询港澳通行证办理进度示例分享
2013/12/27 Python
详解Python当中的字符串和编码
2015/04/25 Python
itchat接口使用示例
2017/10/23 Python
python 3.6 tkinter+urllib+json实现火车车次信息查询功能
2017/12/20 Python
python编写计算器功能
2019/10/25 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
2020/06/08 Python
keras 自定义loss层+接受输入实例
2020/06/28 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
专门经营化妆刷的美国彩妆品牌:Sigma Beauty
2017/09/11 全球购物
瑞典轮胎在线:Tirendo.se
2018/06/21 全球购物
世界领先的艺术图书出版社:TASCHEN
2018/07/23 全球购物
《长城和运河》教学反思
2014/04/14 职场文书
一体化教学实施方案
2014/05/10 职场文书
化学专业自荐信
2014/05/28 职场文书
工作收入证明模板
2015/06/12 职场文书
2015年大学组织委员个人工作总结
2015/10/23 职场文书
OpenCV-Python 实现两张图片自动拼接成全景图
2021/06/11 Python
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS