【React】 第九部分 react 路由
文章目录
9. react 路由
9.1 路由基本使用
下载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>
)
}
}
9.2 一般组件和路由组件的区别
-
写法不同:
- 一般组件:
<Demo/>
- 路由组件:
<Route path="/demo" element={<Demo/>}/>
- 一般组件:
-
存放的位置不同:
- 一般组件:写在
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">About</NavLink>
<NavLink activeClassName='active' className="list-group-item" to="/about">About</NavLink>
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>
9.4 Switch组件的使用
作用: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>
9.5 解决多级路径刷新页面样式丢失的问题
方法一:
在public/index.html
中引入样式的时候不写./
写 /
方法二:
在public/index.html
中引入样式的时候不写./
写 %PUBLIC_URL%
方法三:
使用HashRouter
9.6 Redirect 组件的使用
作用:重定向路由,当没有匹配到任何的路由时,跳转到Redirect所指定的路由
一般写在注册路由的最下方
<Switch>
<Route path="/about" component={About}></Route>
<Route path="/home" component={Home}></Route>
<Redirect to="/about" />
</Switch>
9.7 嵌套路由
嵌套路由需要注意的点:
- 在注册子路由的时候需要在前面加上父路由的path值
- 路由的匹配是按照注册路由的顺序进行的
- 简单来说,父路由先有才会有子路由
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>
)
}
}
9.8 向路由组件传递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>
)
}
}
9.9 向路由组件传递search参数
步骤:
-
在路径中携带好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>
)
}
}
9.10 向路由组件传递state参数
步骤:
-
在路径中携带好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>
)
}
}
9.11 push和replace
push模式 :浏览器可以进行回退(默认开启push模式)
replace模式: 不能进行回退
<Link replace to={`/home/message/detail/${item.id}/${item.title}`}>{item.title}</Link>
9.12 编程式路由导航
编程式路由导航的使用方法基本差不多
说白了就是通过去调用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()
}
9.13 withRouter
作用 : 可以加工一般组件,让一般组件拥有路由组件特有的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)
9.14 BrowserRouter与HashRouter的区别
-
底层原理不一样:
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可以用于解决一些路径错误相关的问题
总结
以上就是今天要讲的内容,希望对大家有所帮助!!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/82861.html