菜單&路由
一虽界、初次上手
最開始在 demo 中寫路由的時(shí)候汽烦,是這樣的:
// container/index.js
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<HashRouter basename="/" >
<div id="nav">
<Sider />
<div id="rightWrap">
<Menu mode="horizontal">
<SubMenu title={<span><Icon type="user" />{this.state.username}</span>}>
<Menu.Item key="setting:1">退出</Menu.Item>
</SubMenu>
</Menu>
<div className="right-box">
<Switch>
<Route path="/" exact render={() => <h1>Home Page</h1>} />
<Route path="/page1" exact component={UserList}></Route>
<Route path="/page2" exact component={PostList}></Route>
<Route path="/page3" exact render={() => <h1>路由測(cè)試</h1>}></Route>
<Route path="/page4" exact render={() => <h1>路由測(cè)試</h1>}></Route>
<Redirect to="/" />
</Switch>
</div>
</div>
</div>
</HashRouter>
);
}
}
// sider/index.jsx
class Sider extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div id="leftMenu">
<span className="logo" style={{marginLeft: '40px'}}>主菜單</span>
<Menu theme="dark"
style={{ width: 200 }}
defaultOpenKeys={['sub1', 'sub2']}
defaultSelectedKeys={[this.state.current]}
mode="inline"
>
<SubMenu key="sub1" title={<span><Icon type="bars" /><span>子菜單</span></span>}>
<Menu.Item key="1"><Link to="/page1">用redux-thunk獲取數(shù)據(jù)</Link></Menu.Item>
<Menu.Item key="2"><Link to="/page2">用redux-saga獲取數(shù)據(jù)</Link></Menu.Item>
<Menu.Item key="3"><Link to="/users">測(cè)試路由</Link></Menu.Item>
<Menu.Item key="4"><Link to="/page4" >測(cè)試路由</Link></Menu.Item>
</SubMenu>
</Menu>
</div>
);
}
}
可以看到涛菠,路由散布在兩個(gè)文件中,意味著每次更改路由的時(shí)候撇吞,都需要更改兩個(gè)地方俗冻,而且還得去找這兩個(gè)文件在哪,可能有時(shí)候修改了一個(gè)地方牍颈,然后運(yùn)行之后點(diǎn)擊的時(shí)候報(bào)錯(cuò)了迄薄,再去修改另一個(gè)地方,這樣是很浪費(fèi)時(shí)間的煮岁。
因此讥蔽,如果能把路由的配置抽出來進(jìn)行集中式的路由管理涣易,每次修改只需在那一個(gè)地方對(duì)路由進(jìn)行修改,是很值得考慮的冶伞。
二新症、集中管理路由
通過路由配置來生成路由的方式是參考了 Material-UI Theme 模板中的寫法。 盡管在使用這個(gè) UI 框架時(shí)响禽,讓我很抓狂徒爹,但是有些地方還是值得學(xué)習(xí)的。┐( ̄ヮ ̄)┌
目錄結(jié)構(gòu)
(1)路由 config
const dashRoutes = [
{
path: '/home',
name: '主菜單',
component: () => <h1>Home Page</h1>
},
{
collapse: true,
name: 'Nav One',
key: 'sub1',
icon: <Icon type="mail" />,
children: [
{
path: '/userList',
name: '用戶列表',
key: 1,
icon: '',
component: UserList
},
{
path: '/postList',
name: '帖子列表',
key: 2,
icon: '',
component: PostList
},
{
path: '/option3',
name: 'Option3',
key: 3,
icon: '',
component: () => <h1>Option3</h1>
},
{
collapse: true,
name: 'Submenu',
key: 'submenu',
icon: '',
children: [
{
path: '/option4',
name: 'Option4',
key: 4,
icon: '',
component: () => <h1>Option4</h1>
},
{
path: '/option5',
name: 'Option5',
key: 5,
icon: '',
component: () => <h1>Option5</h1>
}
]
}
]
},
{
collapse: true,
name: 'Nav Two',
key: 'sub2',
icon: <Icon type="appstore" />,
children: [
{
path: '/Option6',
name: 'Option6',
key: 6,
icon: '',
component: () => <h1>Option6</h1>
},
]
},
{ redirect: true, path: '/', to: '/home', name: '' }
];
(2)根據(jù) config 生成路由
const switchRoutes = (
<Switch>
{dashRoutes.map((prop, key) => {
if (prop.redirect) {
return <Redirect from={prop.path} to={prop.to} key={key} />;
}
if (prop.collapse) {
return prop.children.map((prop, key) => {
if (prop.collapse) {
return prop.children.map((prop, key) => {
return <Route path={prop.path} component={prop.component} key={key} />;
})
}
return <Route path={prop.path} component={prop.component} key={key} />;
});
}
return <Route path={prop.path} component={prop.component} key={key} />;
})}
</Switch>
);
(3)生成左側(cè)菜單
<Menu theme="dark"
style={{ width: 200 }}
defaultOpenKeys={['sub1', 'sub2']}
defaultSelectedKeys={[this.state.current]}
mode="inline"
>
{routes.map((prop, index) => {
if (prop.redirect) return;
if (prop.collapse) {
return (
<SubMenu key={prop.key} title={<span>{prop.icon}<span>{prop.name}</span></span>}>
{prop.children.map((prop, index) => {
if (prop.children) {
return (
<SubMenu key={prop.key} title={<span>{prop.name}</span>}>
{prop.children.map((prop, index) => {
return <Menu.Item key={prop.key}><Link to={prop.path}>{prop.name}</Link></Menu.Item>;
})}
</SubMenu>
)
}
return <Menu.Item key={prop.key}><Link to={prop.path}>{prop.name}</Link></Menu.Item>;
})}
</SubMenu>
)
}
})}
</Menu>
現(xiàn)在只需要在路由配置文件中進(jìn)行統(tǒng)一的路由修改芋类,模塊引入隆嗅,修改 icon 就可以了。
ps:每個(gè)項(xiàng)目的左側(cè)菜單不一樣侯繁,需要根據(jù)實(shí)際情況調(diào)整代碼胖喳,本文只是利用 antd 的 Menu 組件舉個(gè)示例。
?? DEMO(check branch:webpack4+router4)