背景
在管理系統這類項目中,比較常見的設計還是這樣的。
404頁面,宣傳主頁,登錄頁面,註冊頁面,找回密碼頁面單獨處理。
而系統內部就需要統一管理了,不僅僅要管理用戶信息
token的有效性,爲了良好的用戶體驗,我們還有需要使用二級路由。
基礎代碼
老規矩,先上源碼Liz606/webpack-es6-react
講解在這裏:手把手帶你搭建與配置Webpack + ES6 + React開發環境
這時我們就需要使用React的路由工具。從React Router簡介我們可以很清楚的看到使用React Router可以爲我們提供多麼大的便利。
傳統路由
按照傳統的方法,我們需要取獲取window.location.hash
, 在使用`switch-case來分發路由。這樣是可以做的,只是不便於管理。
類似:
import React from 'react';
import ReactDOM from 'react-dom';
import IndexPage from './container/index';
import MainPage from './container/main/index';
import LoginPage from './container/login';
let Child;
class Welcome extends React.Component {
state = {
route: window.location.hash.substr(1)
}
componentDidMount() {
window.addEventListener('hashchange', () => {
this.setState({
route: window.location.hash.substr(1)
})
})
}
render() {
console.log(this.state.route);
switch (this.state.route) {
case '/main': Child = MainPage; break;
case '/login': Child = LoginPage; break;
default: Child = IndexPage;
}
return (<Child />)
}
}
ReactDOM.render(<Welcome />, document.getElementById('root'));
使用Router
使用Router,注意這裏使用的是HashRouter,不是BrowserRouter。這裏的/main不能使用exact 精準匹配,因爲以後我們還需要在/main下添加子頁面。
import React from 'react';
import ReactDOM from 'react-dom';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import IndexPage from './container/index';
import LayoutPage from './container/main/layout';
import LoginPage from './container/login';
import NoPage from './container/noPage';
ReactDOM.render(
<Router>
<Switch>
{/* 去系統主頁 */}
<Route path="/main" component={LayoutPage} />
{/* 去登錄 */}
<Route exact path="/login" component={LoginPage} />
{/* 去首頁 */}
<Route exact path="/index" component={IndexPage} />
{/* 去404 */}
<Route path="*" component={NoPage} />
</Switch>
</Router> , document.getElementById('root'));
多級導航切換路由
在layout內頁容器部分編寫路由,並且添加exact,確保精準匹配。
<Content style={{ margin: '0 16px' }}>
<Router>
<Switch>
<Route exact path='/main/clients/table' component={ClientsTable} />
<Route exact path='/main/clients/new' component={ClientsNew} />
<Route exact path='/main/firms/table' component={FirmsTable} />
<Route exact path='/main/firms/new' component={FirmsNew} />
<Route exact path='/main/account/table' component={AccountTable} />
<Route exact path='/main/account/new' component={AccountNew} />
</Switch>
</Router>
</Content>
注意,菜單hash要與路由精準一致哦。
<Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse}>
<div className="logo"> CRM </div>
<Menu theme="dark" defaultSelectedKeys={['clients']} defaultOpenKeys={['table']} mode="inline">
<SubMenu
key="clients"
title={
<span>
<Icon type="user" />
<span>人才客戶</span>
</span>
}
>
<Menu.Item key="clientsTable"><Link to={'/main/clients/table'}>人才客戶彙總表</Link></Menu.Item>
<Menu.Item key="clientsNew"><Link to={'/main/clients/new'}>新建人才客戶</Link></Menu.Item>
</SubMenu>
<SubMenu
key="firms"
title={
<span>
<Icon type="team" />
<span>企業客戶</span>
</span>
}
>
<Menu.Item key="firmsTable"><Link to={'/main/firms/table'}>企業客戶表彙總表</Link></Menu.Item>
<Menu.Item key="firmsNew"><Link to={'/main/firms/new'}>新建企業客戶</Link></Menu.Item>
</SubMenu>
<SubMenu
key="account"
title={
<span>
<Icon type="area-chart" />
<span>績效彙總</span>
</span>
}
>
<Menu.Item key="accountTable"><Link to={'/main/account/table'}>績效彙總表</Link></Menu.Item>
<Menu.Item key="accountNew"><Link to={'/main/account/new'}>添加新成交</Link></Menu.Item>
</SubMenu>
</Menu>
</Sider>
小Demo
額,爲了美觀…先把antd拿過來用用。
經過簡單的開發,我們有了如下的目錄結構。
│ index.html
│ index.js // 打包入口
│ style.scss // 公共Css
│
├─assets
│ bg.jpg // 靜態文件
│
└─container
│ index.jsx // 宣傳首頁
│ noPage.jsx // 404頁面
│ style.scss
│
├─login
│ index.jsx // 登錄頁面
│ style.scss
│
└─main // 系統內部頁面文件夾,這裏的頁面訪問都需要驗證用戶的身份有效性
│ layout.jsx // 頁面框架,包含header,footer,aside,content
│ style.scss
│ // 再往下都是用於填充content部分的內頁啦
├─account
│ new.jsx
│ table.jsx
│
├─clients
│ new.jsx
│ table.jsx
│
└─firms
new.jsx
table.jsx