ReactRouter
1.安装
npm install --save react-router-dom
2.使用
return (
<Router>
{/* ul内部的相当于是导航栏 <Route></Route>才是跳转语句 */}
{/* 每个Route都需要一个path属性,path属性是一个url,当url匹配一个Route时,
这个Route中component中定义的组件就会被渲染出来。 */}
{/* exact是精确匹配:地址必须是localhost:3000/才能进入首页,/aaa这种包含/的不能进入 */}
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/list/123">列表</Link></li>
</ul>
<Route path="/" exact component={Index}></Route>
<Route path="/list/:id" component={List}></Route>
<Route path="/home/" component={Home}></Route>
</Router>
)
标签嵌套在导航栏内,表明跳转地址。而标签指明对应组件的地址是什么,比如这句话的意思就是如果跳转的地址是"/",那么就渲染Index组件到页面上去。
格式为
exact表示精确匹配,即地址必须和指定的完全一样才能跳转。
3.动态传值
Router
动态传值步骤:
-
设置规则
设置规则格式为
:id
,即:+key
,例如:<Route path="/list/:id" component={List} />
-
传递值
在Link标签上直接传值:
<li><Link to="/list/123">列表</Link> </li>
-
接收值
组件接收传递过来的值的时候,可以在声明周期
componentDidMount
中进行,传递的值在this.props.match
中:componentDidMount() { console.log(this.props) let tempId = this.props.match.params.id this.setState({ id:tempId }) }
-
显示内容
render() { return ( <h2>List-page->{this.state.id}</h2> ); }
4.动态传值2
在平常页面中最常见的路由(动态传值)就是文章的列表页和详细页面,即点击文章的标题就可以跳转到文章的详情页面去查看文章。
首先在Index
组件中的构造器中构造出初始数据,列表数组,就相当于从后台获取到的数据:
constructor(props) {
super(props);
this.state = {
list:[
{cid:123,title:'小明的个人博客-1'},
{cid:456,title:'小明的个人博客-2'},
{cid:789,title:'小明的个人博客-3'},
]
}
}
然后修改一下UI页面使得文章呈列表显示:
render() {
return (
<ul>
{
this.state.list.map((item,index)=>{
return (
<li key={index}> {item.title} </li>
)
})
}
</ul>
)
}
接下去进行路由配置:
先引入Link
:
import { Link } from "react-router-dom";
然后编写路由:
render() {
return (
<ul>
{
this.state.list.map((item,index)=>{
return (
<li key={index}>
<Link to={'/list/'+item.cid}> {item.title}</Link>
</li>
)
})
}
</ul>
)
}
5.重定向
要实现的功能是当进入Index
组件时,然后Index
组件直接重定向到Home
组件。
先随便生成一个Home
组件:
import React, { Component } from 'react';
class Home extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <h2>我是 Home 页面</h2> );
}
}
export default Home;
然后在AppRouter.js
里加一个<Route>
配置,配置时记得要先引入Home
组件:
import Home from './Pages/Home'
<Route path="/home/" component={Home} />
标签式重定向:
要实现重定向,需要先在Index.js
组件中引入Redirect
:
import { Link , Redirect } from "react-router-dom";
引入之后直接在render
中使用:
<Redirect to="/home/" />
编程式重定向:
在构造器中,当组件一渲染的时候就利用JS
进行重定向:
constructor(props) {
super(props);
this.state = {
list:[
//list中的每一行都是一个对象,具有cid和title两个属性
{cid:123,title:'小明的个人博客-1'},
{cid:456,title:'小明的个人博客-2'},
{cid:789,title:'小明的个人博客-3'}
]
}
this.props.history.push("/home/")
}
6.ReactRouter嵌套路由
嵌套路由就是网页中常见的具有一级导航菜单和二级导航菜单的页面,内容随着菜单的不同选择而变化。
首先新建一个Approuter.js
作为首页:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Index from './Pages/Index'
import './index.css'
function AppRouter() {
return (
<Router>
<div className="mainDiv">
<div className="leftNav">
<h3>一级导航</h3>
<ul>
<li> <Link to="/">博客首页</Link> </li>
<li><Link to="">视频教程</Link> </li>
<li><Link to="">职场技能</Link> </li>
</ul>
</div>
<div className="rightMain">
<Route path="/" exact component={Index} />
</div>
</div>
</Router>
);
}
export default AppRouter;
接着在src
目录下新建一个pages
文件夹作为一级子菜单文件夹,然后在里面新建video
和workplace
这两个文件夹作为视频教程和职场技能的文件夹。
然后在index.js
中引入Approuter.js
并进行渲染:
import React from 'react'
import ReactDOM from 'react-dom'
import AppRouter from './AppRouter'
ReactDOM.render(<AppRouter />, document.getElementById('root'));
为了效果更佳美观,可以在src
目录下新建index.css
设计样式:
body{
padding: 0px;
margin: 0px;
}
.mainDiv{
display: flex;
width: 100%;
}
.leftNav{
width: 16%;
background-color: #c0c0c0;
color:#333;
font-size:24px;
height: 1000px;
padding: 20px;
}
.rightMain{
width: 84%;
height:1000px;
background-color: #fff;
font-size:20px;
}
然后可以在video
和workplace
这两个文件夹中新建几个子页面用于内容显示。例如ReactPage.js
:
import React from "react";
function Reactpage(){
return (<h2>我是React页面</h2>)
}
export default Reactpage;
接下去就是二级导航页面video.js
:
import React from "react";
import { Route, Link } from "react-router-dom";
import Reactpage from './video/ReactPage'
import Vue from './video/Vue'
import Flutter from './video/Flutter'
function Video(){
return (
<div>
<div className="topNav">
<ul>
<li><Link to="/video/reactpage">React教程</Link></li>
<li><Link to="/video/vue">Vue教程</Link></li>
<li><Link to="/video/flutter">Flutter教程</Link></li>
</ul>
</div>
<div className="videoContent">
<div><h3>视频教程</h3></div>
<Route path="/video/reactpage/" component={Reactpage} />
<Route path="/video/vue/" component={Vue} />
<Route path="/video/flutter/" component={Flutter} />
</div>
</div>
)
}
export default Video;
然后将二级导航页面引入到主页面,即一级导航页面:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Index from './Pages/Index'
import Video from './Pages/Video'
import './index.css'
function AppRouter() {
return (
<Router>
<div className="mainDiv">
<div className="leftNav">
<h3>一级导航</h3>
<ul>
<li> <Link to="/">博客首页</Link> </li>
// 引入二级导航
<li><Link to="/video/">视频教程</Link> </li>
<li><Link to="">职场技能</Link> </li>
</ul>
</div>
<div className="rightMain">
<Route path="/" exact component={Index} />
// 引入二级导航
<Route path="/video/" component={Video} />
</div>
</div>
</Router>
);
}
export default AppRouter;
美化页面(添加在index.css
中):
.topNav{
height:50px ;
background-color: #cfdefd;
}
.topNav ul{
display: flex;
margin: 0px;
padding: 0px;
}
.topNav li{
padding: 10px;
text-align: center;
list-style: none;
}
.videoContent{
padding:20px;
}
职场技能的二级导航菜单同理
WorkPlace.js
:
import React from "react";
import { Route, Link } from "react-router-dom";
import Money from './workPlace/Money'
import Getup from './workPlace/Getup'
function WorkPlace(){
return (
<div>
<div className="topNav">
<ul>
<li><Link to="/workplace/Moeny">程序员加薪秘籍</Link></li>
<li><Link to="/workplace/Getup">程序员早起攻略</Link></li>
</ul>
</div>
<div className="videoContent">
<div><h3>职场软技能</h3></div>
<Route path="/workplace/Moeny/" component={Money} />
<Route path="/workplace/Getup/" component={Getup} />
</div>
</div>
)
}
export default WorkPlace;
7.后台动态获取路由配置
模拟后台得到的JSON数据,在AppRouter.js
文件里,模拟从后台得到了JSON
字符串,并转换为了对象:
let routeConfig =[
{path:'/',title:'博客首页',exact:true,component:Index},
{path:'/video/',title:'视频教程',exact:false,component:Video},
{path:'/workplace/',title:'职场技能',exact:false,component:Workplace}
]
此时一级导航就不能写死,应该对数据进行遍历:
<ul>
{
routeConfig.map((item,index)=>{
return (<li key={index}> <Link to={item.path}>{item.title}</Link> </li>)
})
}
</ul>
按照上面一样把Route
遍历配置:
{
routeConfig.map((item,index)=>{
return (<Route key={index} exact={item.exact} path={item.path} component={item.component} />)
})
}
AppRouter.js
全部代码:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Index from './Pages/Index'
import Video from './Pages/Video'
import Workplace from './Pages/Workplace'
import './index.css'
function AppRouter() {
let routeConfig =[
{path:'/',title:'博客首页',exact:true,component:Index},
{path:'/video/',title:'视频教程',exact:false,component:Video},
{path:'/workplace/',title:'职场技能',exact:false,component:Workplace}
]
return (
<Router>
<div className="mainDiv">
<div className="leftNav">
<h3>一级导航</h3>
<ul>
{
routeConfig.map((item,index)=>{
return (<li key={index}> <Link to={item.path}>{item.title}</Link> </li>)
})
}
</ul>
</div>
<div className="rightMain">
{
routeConfig.map((item,index)=>{
return (<Route key={index} exact={item.exact} path={item.path} component={item.component} />)
})
}
</div>
</div>
</Router>
);
}
export default AppRouter;