介紹
基於umi搭建一個快速開發框架,react 應用框架。umi 以路由為基礎的,支持類 next.js 的約定式路由,以及各種進階的路由功能,並以此進行功能擴展,比如支持路由級的按需加載。
我們會在基於umi的基礎上,開發出一個框架通用功能和業務功能
框架功能列表
- 全局layout
- 權限管理
- 封裝列表增刪改查
- 國際化
- 集成 g2 chart圖表
- 集成 socket.io
- ....(后續補充)
業務功能
- 用戶管理
- ....(后續補充)
創建項目
umi 提供了腳手架供我們快速創建項目。參考umi腳手架創建項目
包管理器我們推薦用yarn來替換npm,yarn在包安裝速度上確實提升不少
1.在你的空目錄下執行,
yarn create umi
我們需要選擇 antd,code splitting, dll, hard source
2.安裝依賴
yarn
3.啟動本地開發
yarn start
構建全局layout和菜單
umi規定 src/layouts
目錄下存放我們全局layout組件, 在index.js中加入代碼如下
class BaseLayout extends React.Component {
state = {
collapsed: false,
};
onCollapse = (collapsed) => {
console.log(collapsed);
this.setState({ collapsed });
}
render() {
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider
collapsible
collapsed={this.state.collapsed}
onCollapse={this.onCollapse}
>
<div className={styles.logo} />
<MenuComponent />
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }} />
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>User</Breadcrumb.Item>
<Breadcrumb.Item>Bill</Breadcrumb.Item>
</Breadcrumb>
<div style={{ padding: 24, background: '#fff', minHeight: 360 }}>
{this.props.children}
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©2018 Created by Ant UED
</Footer>
</Layout>
</Layout>
);
}
}
export default BaseLayout;
layout 組件需要 MenuComponent
,
在構建組件之前我們需要先mock菜單數據,umi支持mock,我們在mock文件下添加 auth.js
const menu = [
{
id: 1,
name: '概覽',
icon: 'dashboard',
url: '/dashboard',
},
{
id: 2,
name: '系統管理',
icon: 'setting',
url: '/system',
children: [
{
id: 21,
name: '用戶管理',
icon: 'user',
url: '/system/user',
}
]
},
];
menu數據是樹形結構,在項目當中,可以構造放到前台,也可以讓后台小伙伴們返回。比較靈活,我們基於數據去做渲染就行。
還有一個很重要的概念,umi也集成了dva,我們的src/models
路徑下添加auth.js的如下。
import { getMenu } from '../services/auth';
export default {
namespace: 'auth',
state: {
menu: []
},
effects: {
*getMenu(_, { put, select, call }) {
const menu = yield call(getMenu);
yield put({
type: 'setMenu',
payload: menu,
});
},
},
reducers: {
setMenu(state, { payload }) {
return {
...state,
menu: payload,
};
},
},
};
基礎工作已經完成。就可以來構建MenuComponent組件。
@connect(({auth}) => {
return {
menu: auth.menu,
}
})
class MenuComponent extends React.Component {
componentDidMount() {
// 獲取 menu 數據
this.props.dispatch({
type: 'auth/getMenu',
})
}
link = (url) => {
router.push(url);
}
renderMenu = (data) => {
return data && data.map(d => {
if (d.children && d.children.length > 0) {
return <SubMenu
key={d.id}
title={<span><Icon type={d.icon} /><span>{d.name}</span></span>}
>
{this.renderMenu(d.children)}
</SubMenu>
}
return (
<Menu.Item
key={d.id}
onClick={() => {this.link(d.url)}}
>
<Icon type={d.icon} />
<span>{d.name}</span>
</Menu.Item>
)
});
}
render() {
const { menu } = this.props;
return (
<Menu theme='dark'
defaultSelectedKeys={['1']}
mode='inline'>
{
this.renderMenu(menu)
}
</Menu>
);
}
}
export default MenuComponent;
總的來說,menu組件會訪問會調用saga effect,發出異步請求獲取數據,然后通過dva connect獲取menu數據做渲染。
我們刷新瀏覽器看到菜單已經正確渲染了。
結束語
這是開始的第一步,也歡迎大家監督,接下來會逐步把上面提到的功能完善起來。代碼已放到github上,大家可以自行查看umi-react。
我建了一個QQ群,大家加進來,可以一起交流。群號 787846148