上次写了vue+Vue Router多级导航切换路由(页面),发现还有人看,这次就写一个reactJs版的切换路由。
还是秉承着能公用,不重复的思路,将侧导航做成公共组件。将导航做成父页面组件,将切换的页面做成子页面,这样只需调用一次即可。大大减少了后期维护的麻烦
涉及功能点
- 导航支持多级
- reactJs Router
- 子父组件的写法
- 样式:ant.designUI
- Loadable路由懒加载
效果图
01-10-14_27_46.gif目录结构
TIM截图20190110143836.png- app.js是主页面
- main.js是我进行一些模块,变量全局处理的文件
- router下的config.js是路由统一管理的地方
- Menu下的index是导航组件
- contentMain是渲染切换页面的地方
reactJs Router的安装与使用
安装npm install --save react-router-dom
引入import {BrowserRouter} from 'react-router-dom';
本文还用到了路由懒加载
npm install --save react-loadable
上代码!
---app.js
import React, {Component} from 'react';
//全局文件
import './main';
//路由
import {BrowserRouter} from 'react-router-dom';
//布局组件
import CustomMenu from "./components/Menu/index";//导航
import ContentMain from './components/ContentMain'//主题
//UI-antd-按需引入
import 'antd/dist/antd.css';
import {Layout } from 'antd';
const {
Sider, Content,
} = Layout;
let screenHeight= window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
class App extends Component {
render() {
return (
<div className="App" >
<BrowserRouter>
<Layout>
<Sider className="App-customMenu" style={{height:screenHeight}}>
<CustomMenu/>
</Sider>
<Layout>
{/*<Header>Header</Header>*/}
<Content className="App-contentMain" style={{height:screenHeight}}>
<ContentMain/>
</Content>
{/*<Footer>Footer</Footer>*/}
</Layout>
</Layout>
</BrowserRouter>
</div>
);
}
}
export default App;
导航组件menu
注意
global.menus是导航的菜单数据,我这里定义的是全局变量,实际项目时也可以是后台接口请求过来的。
global.menus = [
{
title: '首页',
icon: 'page',
key: '/'
}, {
title: '其它',
icon: 'bulb',
key: '/page/Other',
subs: [
{key: '/page/AlertDemo', title: '弹出框', icon: ''},
]
},
]
renderSubMenu是处理子菜单的方法。renderMenuItem是最子级菜单的路由渲染方法。
Menu是antdUI的组件,其他形式可去其官网了解
import React from 'react'
import {Link} from 'react-router-dom';
import {Menu, Icon} from 'antd';
const menus =global.menus;
//此组件的意义就是将数据抽离出来,通过传递数据去渲染
class CustomMenu extends React.Component {
renderSubMenu = ({key, icon, title, subs}) => {
return (
<Menu.SubMenu key={key} title={<span>{icon && <Icon type={icon}/>}<span>{title}</span></span>}>
{
subs && subs.map(item => {
return item.subs && item.subs.length > 0 ? this.renderSubMenu(item) : this.renderMenuItem(item)
})
}
</Menu.SubMenu>
)
}
renderMenuItem = ({key, icon, title,}) => {
return (
<Menu.Item key={key}>
<Link to={key}>
{icon && <Icon type={icon}/>}
<span>{title}</span>
</Link>
</Menu.Item>
)
}
render() {
return (
<Menu
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
mode="inline"
>
{
menus.map(item => {
return item.subs && item.subs.length > 0 ? this.renderSubMenu(item) : this.renderMenuItem(item)
})
}
</Menu>
)
}
}
export default CustomMenu
---主体渲染组件-CustomMenu
注意
path里的路径,要和你的菜单路径保持一致,这样才能匹配渲染
import React from 'react'
//引入路由
import {Route, Switch} from 'react-router-dom'
class ContentMain extends React.Component {
render() {
return (
<div>
<Switch>
<Route exact path='/' component={global.Main}/>
<Route exact path='/page/general/fromDemo' component={global.FromDemo}/>
<Route exact path='/page/AlertDemo' component={global.Alert}/>
<Route exact path='/page/TableDemo' component={global.Table}/>
<Route exact path='/page/HttpDemo' component={global.HttpDemo}/>
<Route exact path='/page/TreeDemo' component={global.TreeDemo}/>
</Switch>
</div>
)
}
}
export default ContentMain
---路由管理文件
具体路径你自己来定,我这里只做展示
注
Loading也是个组件是展示加载效果的。
//Loadable插件需使用Loading
import Loadable from 'react-loadable'
import Loading from '../components/Loading/index';
//定义路由
global.Main = Loadable({
loader: () => import('../page/index'),
loading: Loading,
});
//表单
当当当 到此就整个导航切换的就完成了,有哪里不明白可以留言,如果帮助到你,就点个赞收个藏吧~~~ 嘻嘻嘻。
有更好的写法欢迎交流讨论~~
网友评论