【13】基础知识:React路由

一、概念

SPA

1、单页Web应用(single page web application,SPA)。

2、整个应用只有一个完整的页面。

3、点击页面中的链接不会刷新页面,只会做页面的局部更新。

4、数据都需要通过 ajax 请求获取,并在前端异步展现。

路由

什么是路由?

1、一个路由就是一个映射关系(key: value)

2、key 为路径,value 可能是 function 或 component

路由分类

1、后端路由

理解:value 是 function,用来处理客户端提交的请求。

注册路由: router.get(path, function(req, res))

工作过程:当 node 接收到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据。

2、前端路由

理解:浏览器端路由,value 是 component,用于展示页面内容。

注册路由: `<Route path="/test" component={Test}>`

工作过程:当浏览器的 path 变为 /test 时,当前路由组件就会变为 Test 组件

react-router-dom

1、react 的一个插件库。

2、专门用来实现一个 SPA 应用。

3、基于 react 的项目基本都会用到此库。

4、安装 react-router-dom:$ npm install --save react-router-dom

react-router:为 React 应用提供了路由的核心功能;

react-router-dom:基于 react-router,加入了在浏览器运行环境下的一些功能;

二、react-router-dom 相关 API

内置组件

1、<BrowserRouter>

2、<HashRouter>

3、<Route>

4、<Redirect>

5、<Link>

6、<NavLink>

7、<Switch>

其它

1、history 对象

2、match 对象

3、withRouter 函数

三、react-router-dom 使用

1、基本路由使用

明确好界面中的导航区、展示区

导航区的 a 标签改为 Link 标签 <Link to="/xxxxx">Demo</Link>

展示区写 Route 标签进行路径的匹配 <Route path='/xxxx' component={Demo}/>

的最外侧包裹了一个或`

2、路由组件 与 一般组件区别

写法不同

一般组件:<Demo/>

路由组件:<Route path="/demo" component={Demo}/>

存放位置不同

一般组件:components 目录

路由组件:pages 目录

接收到的 props 不同

一般组件:写组件标签时传递了什么,就能收到什么

路由组件:接收到三个固定的属性

history:
	go: ƒ go(n)
	goBack: ƒ goBack()
	goForward: ƒ goForward()
	push: ƒ push(path, state)
	replace: ƒ replace(path, state)
location:
	pathname: "/about"
	search: ""
	state: undefined
match:
	params: {}
	path: "/about"
	url: "/about"

NavLink 可以实现路由链接的高亮,通过 activeClassName 指定样式名,NavLink 选中样式类名默认为active。

<NavLink activeClassName="selected" className="list-group-item" to="/about">About</NavLink>

标签体内容(组件标签)是一个特殊的标签属性,通过 this.props.children 可以获取标签体内容。

4、Switch 的使用

通常情况下,path 和 component 是一一对应的关系。

Switch 可以提高路由匹配效率(单一匹配)。

5、解决多级路径刷新页面样式丢失的问题

public/index.html 中 引入样式时不写 ./ 写 / (常用)

public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)

使用 HashRouter (#后面的内容都认为是前端的东西,不会发送给服务端)

6、路由的严格匹配与模糊匹配

默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)

开启严格匹配:<Route exact={true} path="/about" component={About}/>

严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由

7、Redirect 的使用

一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到 Redirect 指定的路由

具体编码

javascript 复制代码
<Switch>
	<Route path="/about" component={About}/>
	<Route path="/home" component={Home}/>
	<Redirect to="/about"/>
</Switch>

8、嵌套路由

注册子路由时要写上父路由的 path 值

路由的匹配是按照注册路由的顺序进行的

9、向路由组件传递参数

params 参数

路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>

注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>

接收参数:this.props.match.params

search参数

路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>

注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>

接收参数:this.props.location.search

备注:获取到的 search 是 urlencoded 编码字符串,需要借助 querystring 解析

安装:$ npm install querystring

引入:import qs from 'querystring'

使用:qs.parse(str)

state参数

路由链接(携带参数):<Link to={``{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>

注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>

接收参数:this.props.location.state

备注:虽然地址栏上没有携带参数,但是刷新也可以保留住参数

依赖于浏览器history对象,清理浏览器缓存后,this.props.location.state 为 null,书写代码时需要做兼容处理

10、编程式路由导航

借助 this.props.history 对象上的 API 对操作路由跳转、前进、后退

javascript 复制代码
this.prosp.history.push()

this.prosp.history.replace()

this.prosp.history.goBack() // 回退

this.prosp.history.goForward() // 前进

this.prosp.history.go(n) // 由传入参数决定,负数后退,正数前进

11、withRouter

withRouter 可以加工一般组件,让一般组件具备路由组件所特有的 API

withRouter 的返回值是一个新组件

javascript 复制代码
import { withRouter } from 'react-router-dom'

class Header extends Component {}
export default withRouter(Header)

12、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 可以用于解决一些路径错误相关的问题。(例如:多层路由样式丢失)

相关推荐
dr李四维17 分钟前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
雯0609~38 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ41 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z1 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five1 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
临枫5411 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript