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 相关文章推荐
jqPlot jquery的页面图表绘制工具
Jul 25 Javascript
为指定元素增加样式的js代码
Dec 09 Javascript
利用jQuery的deferred对象实现异步按顺序加载JS文件
Mar 17 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
Mar 29 Javascript
jquery教程ajax请求json数据示例
Jan 13 Javascript
JavaScript常用验证函数实例汇总
Nov 25 Javascript
Node.js实现批量去除BOM文件头
Dec 20 Javascript
javascript弹出窗口中增加确定取消按钮
Jun 24 Javascript
封装获取dom元素的简单实例
Jul 08 Javascript
在web中js实现类似excel的表格控件
Sep 01 Javascript
解决Vue.js应用回退或刷新界面时提示用户保存修改问题
Nov 24 Javascript
原生js实现拖拽移动与缩放效果
Aug 24 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设置session(过期、失效、有效期)
2015/11/12 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
传智播客学习之java 反射
2009/11/22 Javascript
js特效,页面下雪的小例子
2013/06/17 Javascript
解决css和js的{}与smarty定界符冲突问题的两种方法
2013/09/10 Javascript
js替代copy(示例代码)
2013/11/27 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
2014/10/10 Javascript
JavaScript中的分号插入机制详细介绍
2015/02/11 Javascript
js简单的点击返回顶部效果实现方法
2015/04/10 Javascript
jQuery实现的给图片点赞+1动画效果(附在线演示及demo源码下载)
2015/12/31 Javascript
实例讲解jquery与json的结合
2016/01/07 Javascript
jquery+ajax实现省市区三级联动效果简单示例
2017/01/04 Javascript
javascript观察者模式实现自动刷新效果
2017/09/05 Javascript
switchery按钮的使用方法
2017/12/18 Javascript
Angularjs实现控制器之间通信方式实例总结
2018/03/27 Javascript
vsCode安装使用教程和插件安装方法
2020/08/24 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
vue.js自定义组件实现v-model双向数据绑定的示例代码
2020/01/08 Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
2020/04/09 Javascript
python使用mysql数据库示例代码
2017/05/21 Python
Python常见排序操作示例【字典、列表、指定元素等】
2018/08/15 Python
实例详解python函数的对象、函数嵌套、名称空间和作用域
2019/05/31 Python
Django框架静态文件使用/中间件/禁用ip功能实例详解
2019/07/22 Python
Python 保持登录状态进行接口测试的方法示例
2019/08/06 Python
浅析Python3 pip换源问题
2020/01/06 Python
2分钟教你实现环形/扇形菜单(基础版)
2020/01/15 HTML / CSS
canvas烟花特效锦集
2018/01/17 HTML / CSS
Room Mate Hotels美国:西班牙酒店品牌
2018/04/10 全球购物
纬创Java面试题笔试题
2014/10/02 面试题
工厂总经理岗位职责
2014/02/07 职场文书
精彩的演讲稿开头
2014/05/08 职场文书
服务承诺书怎么写
2014/05/24 职场文书
大专生自我鉴定怎么写
2014/09/16 职场文书
2014年班级工作总结范文
2014/12/23 职场文书
深入浅出的讲解:信号调制到底是如何实现的
2022/02/18 无线电
VUE递归树形实现多级列表
2022/07/15 Vue.js