下载react-router-dom : npm install --save react-router-dom@5
在原生中是依靠a标签实现跳转页面,而在react中是依靠路由链接进行切换组件
在使用路由链接的时候需要注意 : 最外层需要包裹BrowserRouter或者HashRouter,最后会说两个路由器的区别
因为整个引用只能归一个路由器管
import React, { Component } from 'react'
import Home from '../../pages/Home/Home'
import About from '../../pages/About/About'
import { Link, Route,BrowserRouter } from "react-router-dom"
export default class Header extends Component {
render() {
return (
<div>
<BrowserRouter>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header"><h2>React Router Demo</h2></div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 使用路由链接,to表示的是要跳转的路径 */}
<Link className="list-group-item" to="/about">About</Link>
<Link className="list-group-item" to="/home">Home</Link>
</div>
</div>
</div>
<div className="col-xs-6">
{/*
注册路由
path:表示匹配的路径
component:组件
*/}
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
</div>
</BrowserRouter>
</div>
)
}
}
写法不同:
}/> 存放的位置不同:
components文件夹下pages文件夹下接收到的props参数不同:
一般组件:写组件标签的时候,传入什么,就接收到什么
路由组件:可以接收到三个固定的属性
history:
go: ƒ go(n)
goBack: ƒ goBack()
goForward: ƒ goForward()
push: ƒ push(path, state)
replace: ƒ replace(path, state)
location:
pathname: "/home"
search: ""
state: undefined
match:
params: {}
path: "/home"
url: "/home"
NavLink是Link路由组件的升级版
作用:当该组件被触发的时候会给追加一个类名默认为active
activeClassName="xxx" 这个属性可以用来去修改默认类名
export default class Header extends Component {
render() {
return (
<div>
<BrowserRouter>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header"><h2>React Router Demo</h2></div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 使用NavLink,to表示的是要跳转的路径 */}
<NavLink activeClassName='hidden' className="list-group-item" to="/about">About</NavLink>
<NavLink className="list-group-item" to="/home">Home</NavLink>
</div>
</div>
</div>
<div className="col-xs-6">
{/*
注册路由
path:表示匹配的路径
component:组件
*/}
<div className="panel">
<div className="panel-body">
<Route path="/about" component={About}></Route>
<Route path="/home" component={Home}></Route>
</div>
</div>
</div>
</BrowserRouter>
</div>
)
}
}
根据需要对NavLink进行二次封装
import React, { Component } from 'react'
import {NavLink} from "react-router-dom"
export default class MyNavLink extends Component {
render() {
return (
// 举个例子有公共的高亮样式和公共的类,其他通过props传入
/*
知识点:
通过props,标签属性传入key:value形式,props就能够接收到指定的key:value
那么标签体,props其实也是可以接收到,只不过它给我们固定的一个key,名为children
*/
<NavLink activeClassName='active' className="list-group-item" {...this.props}>{this.props.children}</NavLink>
)
}
}
// 二者可以对比一下
<NavLink activeClassName='active' className="list-group-item" to="/about">AboutNavLink>
<NavLink activeClassName='active' className="list-group-item" to="/about">AboutNavLink>
<MyNavLink to="/about">AboutMyNavLink>
<MyNavLink to="/home">HomeMyNavLink>
作用:Switch能够提高匹配路由的效率
那么被Switch组件包裹后,只要匹配到第一个对应的路由那么就会停止匹配
<Switch>
<Route path="/about" component={About}></Route>
<Route path="/a" component={A}></Route>
<Route path="/B" component={B}></Route>
<Route path="/about" component={About}></Route>
</Switch>
方法一:
在public/index.html中引入样式的时候不写./ 写 /
方法二:
在public/index.html中引入样式的时候不写./ 写 %PUBLIC_URL%
方法三:
使用HashRouter
作用:重定向路由,当没有匹配到任何的路由时,跳转到Redirect所指定的路由
一般写在注册路由的最下方
<Switch>
<Route path="/about" component={About}></Route>
<Route path="/home" component={Home}></Route>
<Redirect to="/about" />
</Switch>
嵌套路由需要注意的点:
export default class Home extends Component {
render() {
return (
<div>
<h3>我是Home的内容</h3>
<div>
<ul className="nav nav-tabs">
<li>
<MyNavLink to="/home/news">News</MyNavLink>
</li>
<li>
<MyNavLink to="/home/message">Message</MyNavLink>
</li>
</ul>
</div>
{/* 注册子路由 */}
<Switch>
<Route path="/home/news" component={News}/>
<Route path="/home/message" component={Message}/>
<Redirect to="/home/news"/>
</Switch>
</div>
)
}
}
步骤:
在路径中携带好params参数
通过 :xxx 声明params参数
传入的params参数,可以用this.props.match.params进行接收

export default class Message extends Component {
state = {
messageList:[
{id:1,title:'消息1'},
{id:2,title:'消息2'},
{id:3,title:'消息3'},
]
}
render() {
return (
<ul>
{
this.state.messageList.map((item)=>{
return (
<li key={item.id}>
{/* 传params参数 */}
<Link to={`/home/message/detail/${item.id}/${item.title}`}>{item.title}</Link>
</li>
)
})
}
{/*
注册路由
在这里需要声明params参数
:xx 相当于占位
*/}
<Route path="/home/message/detail/:id/:title" component={Detail}/>
</ul>
)
}
}
步骤:
在路径中携带好search参数
传search参数,其实就是query参数 以 ? 开头 & 进行串联, 形式是key:value
需要注意的是seach参数,react没有像params参数那样帮我们整理好,接收的方式this.props.location.search
获取到的数据类似?id=2&title=消息2,所以可以自己写一个函数去整理得到的参数

export default class Message extends Component {
state = {
messageList:[
{id:1,title:'消息1'},
{id:2,title:'消息2'},
{id:3,title:'消息3'},
]
}
render() {
return (
<ul>
{
this.state.messageList.map((item)=>{
return (
<li key={item.id}>
{/*
传search参数,其实就是query参数
以 ? 开头 & 进行串联
*/}
<Link to={`/home/message/detail?id=${item.id}&title=${item.title}`}>{item.title}</Link>
</li>
)
})
}
{/*
注册路由:
在这里不需要声明search参数
*/}
<Route path="/home/message/detail" component={Detail}/>
</ul>
)
}
}
步骤:
在路径中携带好state参数,以对象的形式
和上述两个参数不同在于:传入的参数不会展示在地址栏
刷新页面也不会丢失

import React, { Component } from 'react'
import {Link, Route} from "react-router-dom"
import Detail from './Detail/Detail'
export default class Message extends Component {
state = {
messageList:[
{id:1,title:'消息1'},
{id:2,title:'消息2'},
{id:3,title:'消息3'},
]
}
render() {
return (
<ul>
{
this.state.messageList.map((item)=>{
return (
<li key={item.id}>
{/*
传state参数 ,以对象的形式
*/}
<Link to={{pathname:'/home/message/detail',state:{id:item.id,title:item.title}}}>{item.title}</Link>
</li>
)
})
}
{/*
注册路由:
在这里不需要声明state参数
*/}
<Route path="/home/message/detail" component={Detail}/>
</ul>
)
}
}
push模式 :浏览器可以进行回退(默认开启push模式)
replace模式: 不能进行回退
{item.title}
编程式路由导航的使用方法基本差不多
说白了就是通过去调用this.props.history下的API对路由跳转进行控制
handlePush = (id,title) =>{
/*
可以参两个参数
- 第一个参数是路径
- 第二个参数是state
*/
// push跳转携带params参数
this.props.history.push(`/home/message/detail/${id}/${title}`)
// push跳转携带search参数
this.props.history.push(`/home/message/detail/?id=${id}&title=${title}`)
// push跳转携带state参数
this.props.history.push('/home/message/detail',{id,title})
}
handleReplace = (id,title) =>{
/*
可以参两个参数
- 第一个参数是路径
- 第二个参数是state
*/
// replace跳转携带params参数
this.props.history.replace(`/home/message/detail/${id}/${title}`)
// replace跳转携带search参数
this.props.history.replace(`/home/message/detail/?id=${id}&title=${title}`)
// replace跳转携带state参数
this.props.history.replace('/home/message/detail',{id,title})
}
handleGo = () =>{
// 可以传入参数,正数表示向前跳转2次
// 可以传入参数,负数表示向后跳转2次
this.props.history.go(2)
this.props.history.go(-2)
}
handleGoBack = () =>{
// 后退一次
this.props.history.goBack()
}
handleGoForward = () =>{
// 前进一次
this.props.history.goForward()
}
作用 : 可以加工一般组件,让一般组件拥有路由组件特有的API
在9.2有述说一般组件和路由组件的不同之处,其中最主要的区别就是接收到的props参数不同
import {withRouter} from 'react-router-dom'
class Header extends Component {
render() {
console.log(this.props);
return (
<div>
</div>
)
}
}
export default withRouter(Header)
底层原理不一样:
BrowserRouter使用的是H5的 history API,不兼容IE9以下的版本
HashRouter使用的是URL的哈希值
path表现得形式不一样:
BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
HashRouter的路径中有#,例如:localhost:3000/#/demo/test
刷新后对路由state参数的影响:
BrowserRouter没有任何的影响,因为state保存在history对象中
HashRouter刷新后会导致路由state参数的丢失
HashRouter可以用于解决一些路径错误相关的问题
以上就是今天要讲的内容,希望对大家有所帮助!!!