前言:此文需要有一定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;
}
}
具體使用
<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. 本地瀏覽
直接在package.json中加入
homepage:'.'
后記:使用react與vue的感悟
react是函數式編程,代碼難度、學習曲度、裝逼指數,社區生態多樣性相比vue更高一點。
vue提供了大量的指令降低了開發難度,詳細完善的文檔,上手更快。
react提供較少的api,相比vue的指令,業務場景的功能需要自己實現,難度更高一點
vue適合中小型項目,單兵、少量人員配合快速開發
react適合大型項目,多人協作
github: https://github.com/treasureDouDou
