react_路由-学习笔记

文章目录

  • 1对SPA应用
  • 2路由的理解
    • 1 什么是路由?
    • 2 路由分类
  • 3前端路由的基础
  • 4 react-router-dom的理解
    • 4.1react-router-dom相关API
  • 5基本使用
  • 6路由组件和一般组件
  • 7封装NavLink组件
  • 8switch
  • 9解决样式丢失
    • 解决办法1
    • 方法2
    • 方法3
    • 总结
  • 10路由模糊匹配
  • 11 Redirect的使用
  • 12、向路由组件传递参数
    • 实例
  • 13push和repalce
  • 14编程式路由导航
  • 15withRouter
  • lazyLoad

1对SPA应用

1 单页Web应用(single page web application,SPA)。
2 整个应用只有一个完整的页面。
3 点击页面中的链接不会刷新页面,只会做页面的局部更新。
4 数据都需要通过ajax请求获取, 并在前端异步展现。

2路由的理解

1 什么是路由?

1.1 一个路由就是一个映射关系(key:value)
1.2 key为路径, value可能是function或component

2 路由分类

1 后端路由:
1.1 理解: value是function, 用来处理客户端提交的请求。
1.2 注册路由: router.get(path, function(req, res))
1.3 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
2 前端路由:
1.1 浏览器端路由,value是component,用于展示页面内容。
1.2 注册路由:
1.3 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件

3前端路由的基础

常用的
react_路由-学习笔记_第1张图片

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端路由的基石_history</title>
</head>
<body>
	<a href="http://www.atguigu.com" onclick="return push('/test1') ">push test1</a><br><br>
	<button onClick="push('/test2')">push test2</button><br><br>
	<button onClick="replace('')">replace test3</button><br><br>
	<button onClick="back()">&lt;= 回退</button>
	<button onClick="forword()">前进 =&gt;</button>

	<script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script>
	<script type="text/javascript">
		// let history = History.createBrowserHistory() //方法一,直接使用H5推出的history身上的API
		let history = History.createHashHistory() //方法二,hash值(锚点)

		function push (path) {
			history.push(path)
			return false
		}

		function replace (path) {
			history.replace(path)
		}

		function back() {
			history.goBack()
		}

		function forword() {
			history.goForward()
		}

		history.listen((location) => {
			console.log('请求路由路径变化了', location)
		})
	</script>
</body>
</html>

4 react-router-dom的理解

1 react的一个插件库。
2 专门用来实现一个SPA应用。
3 基于react的项目基本都会用到此库。

4.1react-router-dom相关API

内置组件

1 <BrowserRouter>
2 <HashRouter>
3 <Route>
4 <Redirect>
5 <Link>
6 <NavLink>
7 <Switch>

其它

1 history对象
2 match对象
3 withRouter函数

5基本使用

通过路由可以不要进入新的html来改变页面
react_路由-学习笔记_第2张图片

yarn add react-router-dom@5.2.0 -S

react_路由-学习笔记_第3张图片

App.jsx

import React, { Component } from 'react'
import {Link,Route} from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'

export default class App extends Component {
	render() {
		return (
			<div>
				<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">

							{/* 原生html中,靠跳转不同的页面 */}
							{/* About
							Home */}

							{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
							<Link className="list-group-item" to="/about">About</Link>
							<Link className="list-group-item" to="/home">Home</Link>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
								{/* 注册路由 */}
								<Route path="/about" component={About}/> 
								<Route path="/home" component={Home}/>
							
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

index.jsx

//引入react核心库
import React from 'react'
//引入ReactDOM
import ReactDOM from 'react-dom'
//
import {BrowserRouter} from 'react-router-dom'
//引入App
import App from './App'

ReactDOM.render(
	<BrowserRouter>
		<App/>
	</BrowserRouter>,
	document.getElementById('root')

./About/index.jsx
react_路由-学习笔记_第4张图片
react_路由-学习笔记_第5张图片

6路由组件和一般组件

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"

7封装NavLink组件

MyNavLink是一般组件,可以把NaviLink中重复的去掉
react_路由-学习笔记_第6张图片

import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
	render() {
		// console.log(this.props);
		return (
			<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
		)
	}
}

App.jsx

import React, { Component } from 'react'
import {Route} from 'react-router-dom'
import Home from './pages/Home' //Home是路由组件
import About from './pages/About' //About是路由组件
import Header from './components/Header' //Header是一般组件
import MyNavLink from './components/MyNavLink'

export default class App extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<Header/>
					</div>
				</div>
				<div className="row">
					<div className="col-xs-2 col-xs-offset-2">
						<div className="list-group">

							{/* 原生html中,靠跳转不同的页面 */}
							{/* About
							Home */}

							{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
							<MyNavLink to="/about">About</MyNavLink>
							<MyNavLink to="/home">Home</MyNavLink>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
								{/* 注册路由 */}
								<Route path="/about" component={About}/>
								<Route path="/home" component={Home}/>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

react_路由-学习笔记_第7张图片

<MyNavLink to="/home">Home</MyNavLink>

也可以写成

<MyNavLink to="/home" children='Home' />

8switch

react_路由-学习笔记_第8张图片
配对到第一个/home后面就不会去看了

9解决样式丢失

localhost:3000对应的是public文件夹
如果请求样式不存在会给index.html
在这里插入图片描述
react_路由-学习笔记_第9张图片
index.html是兜底的
在调用时候会亲求bootstrap地址,具体地址如下
react_路由-学习笔记_第10张图片
样式丢失是多级路径把之前的路由也加入了localhost:3000导致找不到css,刷新后会样式丢失。
在这里插入图片描述

解决办法1

删除点
react_路由-学习笔记_第11张图片在这里插入图片描述
请求路径正确了./是相对路径以当前文件出发,/是从localhost出发

方法2

PUBLIC_URL是public绝对路径
react_路由-学习笔记_第12张图片

方法3

可以保留.,但这里改为hashrouter。#号后面都不会认为是前端资源,都是hash值。
react_路由-学习笔记_第13张图片

react_路由-学习笔记_第14张图片

总结

react_路由-学习笔记_第15张图片

10路由模糊匹配

要home/a/b但只给了/home,给少了连接不上,给多了可以
下图就是给少了
react_路由-学习笔记_第16张图片
开启精准匹配

react_路由-学习笔记_第17张图片
简写方式
react_路由-学习笔记_第18张图片
在这里插入图片描述

11 Redirect的使用

希望一开始就有一个页面,这里用到一个组件redirect,重定向

react_路由-学习笔记_第19张图片
redirect都匹配不上就去redirect内容
react_路由-学习笔记_第20张图片
1.注册子路由时要写上父路由的path值
2.路由的匹配是按照注册路由的顺序进行的

12、向路由组件传递参数

		1.params参数
					路由链接(携带参数):详情
					注册路由(声明接收):
					接收参数:this.props.match.params
		2.search参数
					路由链接(携带参数):详情
					注册路由(无需声明,正常注册即可):
					接收参数:this.props.location.search
					备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
		3.state参数
					路由链接(携带参数):详情
					注册路由(无需声明,正常注册即可):
					接收参数:this.props.location.state
					备注:刷新也可以保留住参数

search要进行解码得到的事urlencoded方法
react_路由-学习笔记_第21张图片

在这里插入图片描述

实例

react_路由-学习笔记_第22张图片
在这里插入图片描述
Message.index

import React, { Component } from 'react'
import {Link,Route} from 'react-router-dom'
import Detail from './Detail'

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		//const {messageArr} = this.state
		//console.log(messageArr)
		return (
			<div>
				<ul>
					{
						this.state.messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>

									{/* 向路由组件传递params参数 */}
									{/* {msgObj.title} */}

									{/* 向路由组件传递search参数 */}
									{/* {msgObj.title} */}

									{/* 向路由组件传递state参数 */}
									<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

								</li>
							)
						})
					}
				</ul>
				<hr/>
				{/* 声明接收params参数 */}
				{/*  */}

				{/* search参数无需声明接收,正常注册路由即可 */}
				{/*  */}

				{/* state参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={Detail}/>

			</div>
		)
	}
}

Message.Detail.index

import React, { Component } from 'react'
// import qs from 'querystring'

const DetailData = [
	{id:'01',content:'你好,中国'},
	{id:'02',content:'你好,尚硅谷'},
	{id:'03',content:'你好,未来的自己'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);

		// 接收params参数
		// const {id,title} = this.props.match.params 

		// 接收search参数
		// const {search} = this.props.location
		// const {id,title} = qs.parse(search.slice(1))

		// 接收state参数
		const {id,title} = this.props.location.state || {}

		const findResult = DetailData.find((detailObj)=>{
			return detailObj.id === id
		}) || {}
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

13push和repalce

每一次路由跳转都会留下痕迹
react_路由-学习笔记_第23张图片
开启replace模式react_路由-学习笔记_第24张图片在这里插入图片描述

react_路由-学习笔记_第25张图片

后退会直接去news,所有路由都开启replace就不会留下痕迹了,一个是替换一个是压栈

14编程式路由导航

点击可以切换路由,都靠了link和NavLink
react_路由-学习笔记_第26张图片
1如果是点击图片跳转如何实现?
1在图片外包裹link
react_路由-学习笔记_第27张图片
2news组件展示后等3秒钟自动往message跳
这种不点的就是编程式路由导航
react_路由-学习笔记_第28张图片

react_路由-学习笔记_第29张图片

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

-this.prosp.history.push()
-this.prosp.history.replace()
-this.prosp.history.goBack()
-this.prosp.history.goForward()
-this.prosp.history.go()

15withRouter

报错undefined,因为是一般组件没有history
,如何让一般组件也用上路由组件的功能。react_路由-学习笔记_第30张图片
react_路由-学习笔记_第31张图片
这时候要用withRouter,它能接收一个一般组件,然后加上路由组件身上属性
react_路由-学习笔记_第32张图片

react_路由-学习笔记_第33张图片

在这里插入图片描述

lazyLoad

react_路由-学习笔记_第34张图片

你可能感兴趣的:(前端,react.js,前端,javascript)