前言:此文需要有一定react,redux基础,具体学习资料请科学上网。
|-src //开发
|----assets //css,img资源
|----unit.js //公用方法
|----routers //路由配置
|----containers //业务逻辑页面
|----component //通用组件
使用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;
}
}
具体使用
import('路径')}>
{Comp => {
return Comp ? : 加载中...
}}
2. 全局loading
配合redux,dispatch => reducer更新 => mapstate更新,在根组件进行loading的渲染
详细请见本demo地址 src/routers/router.js——render函数
3. 配置路由对象
项目布局如下
![](https://user-gold-cdn.xitu.io/2018/4/23/162f045b2e9cc1c5?w=1146&h=313&f=png&s=5068)
本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组件异步加载后塞入组件进行渲染)
{this.props.children}
// Content组件内部
render() {
return (
{this.props.children}
)
}
// 本demo实现,详见src/routers/router.js
(
{initRouters.map(el => this.deepItem(el, { ...this.props, ...item}))}
)}
/>
4. 配置通用reducer
多人配合开发,一些业务场景的组件需要状提升(不理解状态提升的同学,请科学上网)
import otherReducers from './otherReducers'
const App = combineReducers({
rootReducers,
...otherReducers // 其他需要增加的reducers
})
5. 登陆验证
利用withRouter函数,页面进行路由跳转时触发该函数
const newWithRouter = withRouter(props => {
// ....
})
```
若未登录,则返回
return
6. 路由拦截
同上,根据路由配置与权限,返回相应的菜单或屏蔽
return
7. 本地浏览
直接在package.json中加入
homepage:'.'
后记:使用react与vue的感悟
react是函数式编程,代码难度、学习曲度、装逼指数,社区生态多样性相比vue更高一点。
vue提供了大量的指令降低了开发难度,详细完善的文档,上手更快。
react提供较少的api,相比vue的指令,业务场景的功能需要自己实现,难度更高一点
vue适合中小型项目,单兵、少量人员配合快速开发
react适合大型项目,多人协作
github: https://github.com/treasureDouDou