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加ASP二级域名转向的代码
May 17 Javascript
javascript学习笔记(八) js内置对象
Jun 19 Javascript
JS的get和set使用示例
Feb 20 Javascript
深入解读JavaScript中的Hoisting机制
Aug 12 Javascript
vue.js中$watch的用法示例
Oct 04 Javascript
headjs实现网站并行加载但顺序执行JS
Nov 29 Javascript
AngularJS打开页面隐藏显示表达式用法示例
Dec 25 Javascript
vue 2.0封装model组件的方法
Aug 03 Javascript
JS实现的缓冲运动效果示例
Apr 30 Javascript
简单了解前端渐进式框架VUE
Jul 20 Javascript
Element Breadcrumb 面包屑的使用方法
Jul 26 Javascript
基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析
Dec 30 Vue.js
详解开发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中将图片gif,jpg或mysql longblob或blob字段值转换成16进制字符串
2011/08/23 PHP
基于php缓存的详解
2013/05/15 PHP
PHP中exec与system用法区别分析
2014/09/22 PHP
PHP封装的Twitter访问类实例
2015/07/18 PHP
php自动载入类用法实例分析
2016/06/24 PHP
Zend Framework框架实现类似Google搜索分页效果
2016/11/25 PHP
PHP实现双链表删除与插入节点的方法示例
2017/11/11 PHP
用cookies实现的可记忆的样式切换效果代码下载
2007/12/24 Javascript
Javascript var变量隐式声明方法
2009/10/19 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
JS页面延迟执行一些方法(整理)
2013/11/11 Javascript
js导入导出excel(实例代码)
2013/11/25 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
2014/06/12 Javascript
JavaScript截取字符串的2个函数介绍
2014/08/27 Javascript
实例详解JSON数据格式及json格式数据域字符串相互转换
2016/01/07 Javascript
Javascript随机标签云代码实例
2016/06/21 Javascript
jQuery实现的导航下拉菜单效果
2016/07/04 Javascript
Angular利用内容投射向组件输入ngForOf模板的方法
2018/03/05 Javascript
详解React项目如何修改打包地址(编译输出文件地址)
2019/03/21 Javascript
用Python代码来解图片迷宫的方法整理
2015/04/02 Python
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
python构建自定义回调函数详解
2017/06/20 Python
Ubuntu下Python2与Python3的共存问题
2018/10/31 Python
Python read函数按字节(字符)读取文件的实现
2019/07/03 Python
python实现广度优先搜索过程解析
2019/10/19 Python
python GUI库图形界面开发之PyQt5动态加载QSS样式文件
2020/02/25 Python
利用Python实现最小二乘法与梯度下降算法
2021/02/21 Python
英国汽车和货车租赁网站:Hertz英国
2016/09/02 全球购物
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
一家外企的面试题目(C/C++面试题,C语言面试题)
2014/03/24 面试题
考博自荐信
2013/10/25 职场文书
财务会计专业求职信
2014/06/09 职场文书
酒店销售经理岗位职责
2015/04/02 职场文书
团结友爱主题班会
2015/08/13 职场文书
教你如何让spark sql写mysql的时候支持update操作
2022/02/15 MySQL