react-router-dom 实现左侧导航

Posted mosquito18

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react-router-dom 实现左侧导航相关的知识,希望对你有一定的参考价值。

1、介绍react-router-dom

https://reacttraining.com/react-router/web/example/basic 这个官网有很多栗子可以练手

1.1 HashRouter 和BrowserRouter

HashRouter 只能有一个子节点

<HashRouter>
  <div>
    <ul>
      <li>
        <Link to="/main">Home1</Link>
      </li>
      <li>
        <Link to="/about">About1</Link>
      </li>
    </ul>
  </div>
</HashRouter>

 

http://localhost:3000/#/admin/buttons         //HashRouter是根路由
http://localhost:3000/admin/buttons         //BrowserRouter,主要用于前后端分离的时候使用

1.2 Route

exact={true}精确匹配

 <Route exact={true} path="/" component={Home} />

 

<Route path="/common" render={() =>
      <Common>
          <Route path="/common/order/detail/:orderId" component={OrderDetail} />
      </Common>
    }
 />

1.3 Link 导航

<div>
  <ul>
    <li>
      <Link to="/main">Home1</Link>
    </li>
    <li>
      <Link to="/about">About1</Link>
    </li>
  </ul>
</div>

to 实现路由跳转

to还可传对象

<Link to={{pathname:‘/three/7‘}}>Three #7</Link>

//一个基本的location对象
{pathname:‘/‘,search:‘‘,hash:‘‘,key:‘123‘,state:{}}

定义

<Route path="/three/:number" />

取值:

this.props.match.params.number

1.4 Switch 匹配多个路由

<Route path="/" render={()=>
  <Admin>
    <Switch>
      <Route path=‘/home‘ component={Home} />
      <Route path="/ui/buttons" component={Buttons} />
      <Route path="/ui/modals" component={Modals} />
      <Redirect to="/home" />、
    </Switch>
  </Admin>         
} />

  匹配到一个就不会往下执行

1.5 Redirect 路由重定向

<Redirect to="/home" />

 2、举栗子

2.1 简单例子

import React from ‘react‘
import {HashRouter , Route , Link, Switch} from ‘react-router-dom‘
import Main from ‘./Main‘
import About from ‘./about‘
import Topic from ‘./topic‘
export default class Home extends React.Component{

    render(){
        return (
            <HashRouter>
                <div>
                    <ul>
                        <li>
                            <Link to="/">Home</Link>
                        </li>
                        <li>
                            <Link to="/about">About</Link>
                        </li>
                        <li>
                            <Link to="/topics">Topics</Link>
                        </li>
                    </ul>
                    <hr/>
                    <Switch>
                        <Route exact={true} path="/" component={Main}></Route>
                        <Route path="/about" component={About}></Route>
                        <Route path="/topics" component={Topic}></Route>
                    </Switch>
                </div>
            </HashRouter>
        );
    }
}

2.2 嵌套子路由、获取动态路由、未匹配路由

 Home.js

import React from ‘react‘
import { Link } from ‘react-router-dom‘
export default class Home extends React.Component {

    render() {
        return (
            <div>
                <ul>
                    <li>
                        <Link to="/main">Home1</Link>
                    </li>
                    <li>
                        <Link to="/about">About1</Link>
                    </li>
                    <li>
                        <Link to="/topics">Topics1</Link>
                    </li>
                    <li>
                        <Link to="/mosquito1">mosquito1</Link>
                    </li>
                    <li>
                        <Link to="/mosquito2">mosquito2</Link>
                    </li>
                </ul>
                <hr />
                {this.props.children}
            </div>
        );
    }
}

router.js

import React from ‘react‘
import { HashRouter as Router, Route, Link, Switch} from ‘react-router-dom‘
import Main from ‘./Main‘
import Info from ‘./info‘
import About from ‘./../route1/about‘
import Topic from ‘./../route1/topic‘
import Home from ‘./Home‘
import NoMatch from ‘./NoMatch‘
export default class IRouter extends React.Component{

    render(){
        return (
            <Router>
                <Home>
                    <Switch>
                        <Route path="/main" render={() =>
                            <Main>
                                <Route path="/main/:value" component={Info}></Route>
                            </Main>
                        }></Route>
                        <Route path="/about" component={About}></Route>
                        <Route exact={true} path="/about/abc" component={About}></Route>
                        <Route path="/topics" component={Topic}></Route>
                        <Route component={NoMatch}></Route>
                    </Switch>
                </Home>
            </Router>
        );
    }
}

Main.js

import React from ‘react‘
import { Link } from ‘react-router-dom‘
export default class Main extends React.Component {

    render() {
        return (
            <div>
                this is main page.
                <br/>
                <Link to="/main/test-id">嵌套路由1</Link>
                <br/>
                <Link to="/main/456">嵌套路由2</Link>
                <hr/>
                {this.props.children}
            </div>
        );
    }
}

info.js

import React from ‘react‘
export default class Info extends React.Component {

    render() {
        return (
            <div>
                这里是测试动态路由功能。
                动态路由的值是:{this.props.match.params.value}
            </div>
        );
    }
}

NoMatch.js

import React from ‘react‘
export default class Home extends React.Component {

    render() {
        return (
            <div>
                404 No Pages.
            </div>
        );
    }
} 

注意:

                <Home>
                    <Route path="/main" render={()=>
                        <Main>
                            <Route path="/main/a" component={About}></Route>
                        </Main>   
                    }></Route>
                    <Route path="/about" component={About}></Route>
                    <Route path="/topics" component={Topic}></Route>
                </Home>

1.render后的箭头函数不要加大括号,这样就不是返回了,而是执行里面的函数

2.有子路由的Route不能使用 exact={true} 精确匹配,不然子路由无法匹配

3.导入时可为HashRouter 取别名

import {HashRouter as Router,Route,LinK} from ‘react-router-dom‘

4.页面展示的内容通过 this.props.children

5.写动态子路由

<Route path="/main/:value" component={Info}></Route>

获取动态子路由

{this.props.match.params.value}

6.未匹配的路由

<Route component={NoMatch}></Route>

同时需要使用<Switch>标签,不然有子路由的算无法匹配而进入NoMatch组件

3、左侧导航栏

antd-design 有 Menu导航菜单,但是如果菜单栏的配置是后台给的话,需要遍历数据获取

 

首先配置router.js

<HashRouter>
  <App>
    <Switch>
      <Route path="/login" component={Login}/>
          <Route path="/common" render={() =>
        <Common>
          <Route path="/common/order/detail/:orderId" component={OrderDetail} />
         </Common>
        }
      />
          <Route path="/" render={()=>
        <Admin>
          <Switch>
            <Route path=‘/home‘ component={Home} />
                    <Route path="/ui/buttons" component={Buttons} />
                    <Route path="/ui/modals" component={Modals} />
                    <Route path="/ui/loadings" component={Loadings} />
                    <Route path="/ui/notification" component={Notice} />
                    <Route path="/ui/messages" component={Messages} />
                    <Route path="/ui/tabs" component={Tabs} />
                    <Route path="/ui/gallery" component={Gallery} />
                    <Route path="/ui/carousel" component={Carousel} />
                    <Route path="/form/login" component={FormLogin} />
                    <Route path="/form/reg" component={FormRegister} />
                    <Route path="/table/basic" component={BasicTable} />
                    <Route path="/table/high" component={HighTable} />
                    <Route path=‘/rich‘ component={Rich} />
                    <Route path="/city" component={City} />
                    <Route path="/order" component={Order} />
                    <Route path=‘/bikeMap‘ component={BikeMap} />
                    <Route path=‘/user‘ component={User} />
                    <Route path="/charts/bar" component={Bar} />
                    <Route path="/charts/pie" component={Pie} />
                    <Route path="/charts/line" component={Line} />
                    <Route path="/permission" component={Permission} />
                    <Redirect to="/home" />
                    {/* <Route component={NoMatch} /> */}
          </Switch>
        </Admin>         
      } />
    </Switch>
  </App>
</HashRouter>

 

menuConfig.js文件

const menuList = [
    {
        title: ‘首页‘,
        key: ‘/home‘
    },
    {
        title: ‘UI‘,
        key: ‘/ui‘,
        children: [
            {
                title: ‘按钮‘,
                key: ‘/ui/buttons‘,
            },
            {
                title: ‘弹框‘,
                key: ‘/ui/modals‘,
            },
            {
                title: ‘Loading‘,
                key: ‘/ui/loadings‘,
            },
            {
                title: ‘通知提醒‘,
                key: ‘/ui/notification‘,
            },
            {
                title: ‘全局Message‘,
                key: ‘/ui/messages‘,
            },
            {
                title: ‘Tab页签‘,
                key: ‘/ui/tabs‘,
            },
            {
                title: ‘图片画廊‘,
                key: ‘/ui/gallery‘,
            },
            {
                title: ‘轮播图‘,
                key: ‘/ui/carousel‘,
            }
        ]
    },
    {
        title: ‘表单‘,
        key: ‘/form‘,
        children: [
            {
                title: ‘登录‘,
                key: ‘/form/login‘,
            },
            {
                title: ‘注册‘,
                key: ‘/form/reg‘,
            }
        ]
    },
    {
        title: ‘表格‘,
        key: ‘/table‘,
        children: [
            {
                title: ‘基础表格‘,
                key: ‘/table/basic‘,
            },
            {
                title: ‘高级表格‘,
                key: ‘/table/high‘,
            }
        ]
    },
    {
        title: ‘富文本‘,
        key: ‘/rich‘
    },
    {
        title: ‘城市管理‘,
        key: ‘/city‘
    },
    {
        title: ‘订单管理‘,
        key: ‘/order‘,
        btnList: [
            {
                title: ‘订单详情‘,
                key: ‘detail‘
            },
            {
                title: ‘结束订单‘,
                key: ‘finish‘
            }
        ]
    },
    {
        title: ‘员工管理‘,
        key: ‘/user‘
    },
    {
        title: ‘车辆地图‘,
        key: ‘/bikeMap‘
    },
    {
        title: ‘图标‘,
        key: ‘/charts‘,
        children: [
            {
                title: ‘柱形图‘,
                key: ‘/charts/bar‘
            },
            {
                title: ‘饼图‘,
                key: ‘/charts/pie‘
            },
            {
                title: ‘折线图‘,
                key: ‘/charts/line‘
            },
        ]
    },
    {
        title: ‘权限设置‘,
        key: ‘/permission‘
    },
];
export default menuList;

navleft.js

import React from "react";
import { Menu, Icon } from "antd";
import { NavLink } from "react-router-dom";
import MenuConfig from "./../../config/menuConfig";
import "./index.less";
const SubMenu = Menu.SubMenu;
export default class NavLeft extends React.Component {

  componentWillMount() {
    const menuTreeNode = this.renderMenu(MenuConfig);

    this.setState({
      menuTreeNode
    });
  }
  // 菜单渲染
  renderMenu = data => {
    return data.map(item => {
      if (item.children) {
        return (
          <SubMenu title={item.title} key={item.key}>
            {this.renderMenu(item.children)}
          </SubMenu>
        );
      }
      return (
        <Menu.Item title={item.title} key={item.key}>
          <NavLink to={item.key}>{item.title}</NavLink>
        </Menu.Item>
      );
    });
  };
  render() {
    return (
      <div>
        <div className="logo">
          <img src="/assets/logo-ant.svg"  />
          <h1>Imooc MS</h1>
        </div>
        <Menu onClick={this.handleClick} theme="dark">
          {this.state.menuTreeNode}
        </Menu>
      </div>
    );
  }
}

navleft.less

.nav-left{
    .logo{
        line-height: 90px;
        padding-left: 20px;
        background-color: #002140;
        img{
            height: 35px;
        }
        h1{
            color: #ffffff;
            font-size: 20px;
            display: inline-block;
            vertical-align: middle;
            margin: 0 0 0 10px;
        }
    }
}

admin.js

            <Row className="container">
                <Col span="4" className="nav-left">
                    <NavLeft/>
                </Col>
                <Col span="20" className="main">
                    <Header/>
                    <Row className="content">
                        {/* <Home/> */}
                        {this.props.children}
                    </Row>
                    <Footer/>
                </Col>
            </Row>

 

admin.less

.container{
    .nav-left{
        background-color:#001529;
        color: #ffffff;
        height: calc(100vh);
    }
    .main{
        height: calc(100vh);
        background-color: @colorL;
        overflow: auto;
    }
    .content{
        position: relative;
        padding: 20px;
    }
}

 效果:

技术分享图片

 

      




以上是关于react-router-dom 实现左侧导航的主要内容,如果未能解决你的问题,请参考以下文章

android 怎么实现左侧推出导航菜单

左侧竖条导航栏点击出现效果的实现

CSS 模块在使用 react-router-dom 的导航栏上是“未定义的”

delphi左侧导航栏收缩

SpringMVC+EasyUI实现页面左侧导航菜单

使用jsonp形式跨域访问实现电商平台的左侧导航栏