您的当前位置:首页正文

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

2020-11-27 来源:筏尚旅游网

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

使用create-react-app脚手架

具体基础配置请参考

配合antd组件实现的管理系统demo,线上地址

开发前反思

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. 配置路由对象

项目布局如下

本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适合大型项目,多人协作

显示全文