介紹
基於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
對上面有些內容不理解的同學參考如下內容
umi 官網
dva 官網