react路由基础

1、相关理解

Ⅰ-SPA的理解

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

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

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

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

Ⅱ-路由的理解

根据不同的路径,显示不同的组件(内容)

  • 前端路由功能:让用户从一个视图(页面)导航到另一个视图(页面)
  • 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系

Ⅲ-react-router-dom的理解

①相关概念

  1. react的一个插件库。

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

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

②相关api

1、内置组件
  1. <BrowserRouter>

  2. <HashRouter>

  3. <Route>

  4. <Redirect>

  5. <Link>

  6. <NavLink>

  7. <Switch>

2、其他
  1. history对象

  2. match对象

  3. withRouter函数

2、路由的基本使用

1.<App>的最外侧包裹了一个<BrowserRouter>或<HashRouter> App.js
使用H5的history API实现(localhost3000/first)
使用URL的哈希值实现 (localhost:3000/#/first)

import {BrowserRouter } from "react-router-dom" //按需导入
ReactDOM.render(
	<BrowserRouter>
		<App/>
	</BrowserRouter>,
	document.getElementById('root')
)

2.展示区写Route标签进行路径的匹配

import { Route, Switch, Redirect } from "react-router-dom";
import Home from "../pages/Home/Home"
import User from "../pages/User/User"
import Animate from "../pages/Animate/Animate"
export default function MyRouter() {
 return (
     <Switch>
         {/* 主页路由要加exact精确匹配,因为每一个路径都有/,不精确下,都会匹配主页 */}
         <Route exact path="/home" component={Home} />
         {/* 正常路由建议加exact, 动态路由因为路径不固定, 不能加exact */}
         <Route exact path="/user" component={User} />
         {/* Redirect 用于路由重定向 */}
         {/* <Redirect path="/" to="/home"/> */}
         <Route exact path="/Animate" component={Animate} />
     </Switch>
 )
}

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

import {Link} from "react-router-dom" //按需导入
<Link to="/xxxxx">Demo</Link>
<RouterView></RouterView>

3、路由组件与一般组件

1.写法不同:

​ 一般组件:<Demo/>

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

2.存放位置不同:

​ 一般组件:components

​ 路由组件:pages
3. 接收到的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"

4、NavLink使用与封装

  1. NavLink可以实现路由链接的高亮,通过activeClassName指定样式名 ,未点击没效果

  2. 封装

//封装示例
export default class MyNavLink extends Component {
	render() {
		return (
			<NavLink activeClassName="atguigu" {...this.props}/>
		)
	}
}
  1. 使用与调用
{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
	<MyNavLink to="/about">About</MyNavLink>
	<MyNavLink to="/home">Home</MyNavLink>

5、Switch的使用

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

2.Switch可以提高路由匹配效率(单一匹配) ---- 即匹配到一个后将不再往下匹配

<Switch>
	<Route path="/about" component={About}/>
	<Route path="/home" component={Home}/>
	<Route path="/home" component={Test}/>
</Switch>

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

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

2.public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用,但只在react中有效果)

3.使用HashRouter (不常用)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>react脚手架</title>
  <!-- 方法二 -->
		<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <!-- 方法一 -->
		<link rel="stylesheet" href="/css/bootstrap.css">
	</head>
	<body>
		<div id="root"></div>
	</body>
</html>

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

  1. 默认使用的是模糊匹配

  2. 开启严格匹配:<Route exactpath=“/about” component={About}/>

  3. 正常路由建议加exact, 动态路由因为路径不固定, 不能加exact

 {/* 添加个人页的动态路由用于传值 */}
 <Route path="/user/:title" component={User} />

8、Redirect的使用

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

  2. 具体编码:

	<Switch>
		<Route path="/about" component={About}/>
		<Route path="/home" component={Home}/>
		<Redirect to="/about"/>
	</Switch>

9、路由跳转

  1. 声明式导航:link标签跳转

  2. 编程式导航:通过JS代码来实现页面跳转

this.props.history.push()

10、路由传值

Ⅰ-url拼接传值(麻烦,不推荐使用)

//编程式导航
 this.props.history.push('/user?title='+title) 
  1. 路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
  2. 注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
  3. 接收参数:this.props.location.search
  4. 备注:获取到的search是urlencoded编码字符串,需要解析
	-------------------------------发送参数:父组件----------------------------------------------
	<div>
 	{/* 向路由组件传递search参数 */}
		<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>
  <hr />
	{/* search参数无需声明接收,正常注册路由即可 */}
		<Route path="/home/message/detail" component={Detail}/>
</div>
	--------------------------------接受参数:子组件-----------------------------------------------------------
export default function User (props){
	return <div className="user">
       <h3>路由url拼接传值: {decodeURI(props.location.search)}</h3>
       <h3>动态路由传值: {props.match.params.title}</h3>
       <h3>自定义对象传值: {props.location.data && props.location.data.title}></h3>
   </div>
}

Ⅱ-动态路由(友好型url)传值

//编程式导航
  this.props.history.push('/user/'+title) 
  1. 路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>

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

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

	-------------------------------发送参数:父组件----------------------------------------------
	<div>
  {/* 向路由组件传递params参数 */}
  <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
  <hr />
  {/* 声明接收params参数 */}
  <Route path="/home/message/detail/:id/:title" component={Detail} />
</div>
	--------------------------------接受参数:子组件-----------------------------------------------------------
const {id,title} = this.props.match.params

Ⅲ-自定义对象传值

//编程式导航
 this.props.history.push({
        pathname: "/user",
        data: { title }
    })
  1. 路由链接(携带参数):[<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>]
  2. 注册路由(无需声明,正常注册即可):[<Route path="/demo/test" component={Test}/>]
  3. 接收参数:this.props.location.state
  • 备注:使用BrowserRouter刷新才可以保留住参数,使用HashRouter刷新后state将会没有history来保存参数
  • 子组件接受参数时const {id,title} = this.props.location.state || {} ,后面添加||{}是防止使用HashRouter后state为undefined时报错
	-------------------------------发送参数:父组件----------------------------------------------
	<div>
 	{/* 向路由组件传递state参数 */}
		<Link to={{pathname:'/home/message/detail',date:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

  <hr />
	{/* state参数无需声明接收,正常注册路由即可 */}
		<Route path="/home/message/detail" component={Detail}/>
</div>
	--------------------------------接受参数:子组件-----------------------------------------------------------
// 接收date参数,后面添加`||{}`是防止使用`HashRouter`后date为undefined时报错
	const {id,title} = this.props.location.date || {}

Ⅳ-对比区别

1, url路径传值 优点: 传值简单 缺点: 取值是url编码后的字符串,解析麻烦
2, 动态路由传值 优点: 取值方便 缺点: 配置麻烦
3, 自定义对象传值 优点: 传值取值简单方便 缺点: 网页刷新数据会丢失,需要结合storage

总结, 建议使用动态路由传值

11、编程式路由导航

  1. -this.props.history.push()

将历史记录压入栈

  1. -this.props.history.replace()

替代栈位置,即不会产生历史记录

  1. -this.props.history.goBack()

回退一格

  1. -this.props.history.goForward()

前进一格

  1. -this.props.history.go()

前进或者后退n格(根据传入的数字正负数)

12、withRouter的使用

  1. withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
  2. withRouter的返回值是一个新组件
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
class Header extends Component {
back = () => { this.props.history.goBack()}
forward = () => {this.props.history.goForward()}
go = () => { this.props.history.go(-2)}
render() {
console.log('Header组件收到的props是', this.props);
return (
<div className="page-header">
  <h2>React Router Demo</h2>
  <button onClick={this.back}>回退</button>&nbsp;
  <button onClick={this.forward}>前进</button>&nbsp;
  <button onClick={this.go}>go</button>
</div>
)
}
}
export default withRouter(Header)

13、BrowserRouter与HashRouter的区别

备注:HashRouter可以用于解决一些路径错误相关的问题。即在问题6中引入文件时可以不进行路径修改

Ⅰ-底层原理不一样:

  1. BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。

但一般来说都用的这个

  1. HashRouter使用的是URL的哈希值。

Ⅱ-path表现形式不一样

  1. BrowserRouter的路径中没有#,例如:localhost:3000/demo/test

  2. HashRouter的路径包含#,例如:localhost:3000/#/demo/test

Ⅲ-刷新后对路由state参数的影响

  1. BrowserRouter没有任何影响,因为state保存在history对象中。

  2. HashRouter刷新后会导致路由state参数的丢失!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值