React-Router5路由相关一(路由相关概念、基本使用、NavLink与NavLink的封装、Switch的使用、严格匹配、路由重定向、路由组件与一般组件的区别)(五)

系列文章目录

第一章:React基础知识(React基本使用、JSX语法、React模块化与组件化)(一)
第二章:React基础知识(组件实例三大核心属性state、props、refs)(二)
第三章:React基础知识(事件处理、受控组件与非受控组件、高阶函数、组件的生命周期)(三)
第四章:React脚手架应用(创建脚手架、代理配置、ajax相关、组件通信)(四)
第五章:react-router5路由相关一(路由相关概念、基本使用、NavLink与NavLink的封装、Switch的使用、严格匹配、路由重定向、路由组件与一般组件的区别)(五)
第六章:react-router5路由相关二(嵌套路由、路由传参、replace、编程式路由导航、withRouter的使用、BrowserRouter与HashRouter的区别)(六)
第七章:React-Router6路由相关一(路由的基本使用、重定向、NavLink·、路由表、嵌套路由)(七)
第八章:React-Router6路由相关二(路由传参、编程式路由导航、路由相关hooks)(八)
第九章:React相关扩展一(setState、lazyLoad、Hooks相关)(九)
第十章:React相关扩展二(Fragment、Content、组件优化、render props、错误边界)(十)
第十一章:Redux相关知识(什么是redux、redux的工作原理、redux的核心概念、redux的基本使用)(十一)
第十二章:React-Redux相关知识(什么是react-redux、react-redux的原理、react-redux相关API、react-redux的基本使用)(十二)



一、路由相关概念

1.1 SPA的理解

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

1.2 路由的理解

1.什么是路由?

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

2.路由分类

  • 后端路由:

1)理解: value是function, 用来处理客户端提交的请求。
2)注册路由: router.get(path, function(req, res))
3)工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由,调用路由中的函数来处理请求, 返回响应数据

  • 前端路由:

1)浏览器端路由,value是component,用于展示页面内容。
2)注册路由:
3)工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件

3. react-router-dom的理解

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

二、路由常用组件的基本使用

2.1 安装

$ npm install react-router-dom@5 --save

安装react-router-dom的产品依赖,会帮助我们将路由操作dom的依赖安装完成

注意: 在跳转路由时,如果路径是/开头的则是绝对路由,否则为相对路由,即相对于“当前URL”进行改变。

  • Redirect组件

    可以进行路由的重定向

2.2 基本使用步骤

1.明确好界面中的导航区、展示区
2.导航区写Link标签<Link to="/xxxxx">Demo</Link>
3.展示区写Route标签进行路径的匹配<Route path='/xxxx' component={Demo}/>
4.的最外侧包裹了一个<BrowserRouter><HashRouter>

  • BrowserRouter、HashRouter组件

    路由的根组件。

  • Link组件

    其中Link标签对A标签进行了封装,可以进行路由的跳转;Link组件只能在Router内部使用,因此使用到Link组件的组件一定要放在顶层的Router之内。

  • Route组件

    Route组件则是用来匹配路由对应的页面组件

代码片段(为节省空间,样式代码,一律不写):

App.js

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中,靠<a>跳转不同的页面 */}
							{/* <a className="list-group-item" href="./about.html">About</a>
							<a className="list-group-item active" href="./home.html">Home</a> */}

							{/* 在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>
		)
	}
}

Home.jsx

import React, { Component } from 'react'

export default class Home extends Component {
	render() {
		return (
			<h3>我是Home的内容</h3>
		)
	}
}

About.jsx

import React, { Component } from 'react'

export default class About extends Component {
	render() {
		return (
			<h3>我是About的内容</h3>
		)
	}
}

index.js

//引入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')
)

运行结果:
在这里插入图片描述

2.3 NavLink的使用

  • NavLink组件
    • NavLink组件和Link组件的功能是一致的,区别在于可以判断其to属性是否是当前匹配到的路由
    • NavLink可以实现路由链接的高亮,通过activeClassName指定样式名,这里的Link或NavLink类似于Vue中的Router-link。

代码片段:(为节省空间,该案例Home、About、index的代码和上述第一个案例一致,不在重复描述):
App.js

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

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">

							{/* 在React中靠路由链接实现切换组件--编写路由链接,可以通过activeClassName自定义选中样式,如果不设置,就使用默认样式 */}
							<NavLink activeClassName="mystyle" className="list-group-item" to="/about">About</NavLink>
							<NavLink activeClassName="mystyle" className="list-group-item" to="/home">Home</NavLink>
						</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.html

<!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">
	<style>
			/* 设置样式 */
		.mystyle {
			background-color: rgb(209, 137, 4) !important;
			color: white !important;
		}
	</style>
</head>

<body>
	<div id="root"></div>
</body>

</html>

运行结果:
在这里插入图片描述

2.4 封装自己的NavLink

代码片段(为节省空间,该案例Home、About、index的代码和上述第一个案例一致,不在重复描述):

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">

							{/* 在React中靠路由链接实现切换组件--编写路由链接 ,标签内部数据,子组件也可以通过props接收*/}
							<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>
		)
	}
}

MyNavLink.jsx

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="mystyle" className="list-group-item" {...this.props}/>
		)
	}
}

运行结果:
在这里插入图片描述

2.5 Switch的使用

  • Switch组件
    1.通常情况下,path和component是一一对应的关系。
    2.Switch可以提高路由匹配效率(单一匹配)。
    3.Switch功能上类似于Vue中的Router-view。将来匹配到的路由组件将会被加载到Switch所在的位置。Switch组件内部存放Route组件。

代码片段(为节省空间,该案例MyNavLink.jsx、Home、About、index的代码和上述第三个案例一致,不在重复描述):

App.js

import React, { Component } from 'react'
import {Route,Switch} 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'
import Test from './pages/Test'

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">

							{/* 在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">
								{/* 注册路由 ,当路由匹配中出现两个一样的路径时,使用Switch后只会匹配第一个*/}
								<Switch>
									<Route path="/about" component={About}/>
									<Route path="/home" component={Home}/>
									<Route path="/home" component={Test}/>
								</Switch>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

Test.jsx

import React, { Component } from 'react'

export default class Test extends Component {
	render() {
		return (
			<div>
				<h2>Test....</h2>
			</div>
		)
	}
}

运行结果:

不使用Switch前:
在这里插入图片描述
使用后:
在这里插入图片描述

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

1.public/index.html 中 引入样式时不写 ./ 写 / (常用)
2.public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
3.使用HashRouter

代码片段(为节省空间,该案例MyNavLink.jsx、Home、About、index的代码和上述第三个案例一致,不在重复描述):
App.js

import React, { Component } from 'react'
import {Route,Switch} 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">
							{/* 在React中靠路由链接实现切换组件--编写路由链接,使用多级路径 */}
							<MyNavLink to="/api/about">About</MyNavLink>
							<MyNavLink to="/atguigu/home">Home</MyNavLink>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
								{/* 注册路由 */}
								<Switch>
									<Route path="/api/about" component={About}/>
									<Route path="/api/home" component={Home}/>
								</Switch>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

index.html

<!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">
	<style>
		/* 设置样式 */
		.mystyle {
			background-color: rgb(209, 137, 4) !important;
			color: white !important;
		}
	</style>
</head>

<body>
	<div id="root"></div>
</body>

</html>

运行结果:
修改前:
在这里插入图片描述

修改后:
在这里插入图片描述

2.7 路由的严格匹配与模糊匹配

1.默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致,就可以转跳)
2.开启严格匹配:<Route exact={true} path="/about" component={About}/>
3.严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由

代码片段(为节省空间,该案例MyNavLink.jsx、Home、About、index的代码和上述第三个案例一致,不在重复描述):

App.js

import React, { Component } from 'react'
import {Route,Switch} 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">

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

运行结果:
模糊匹配:

在这里插入图片描述

精准匹配:
在这里插入图片描述

2.8 Redirect的使用

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

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

代码片段(为节省空间,该案例MyNavLink.jsx、Home、About、index的代码和上述第三个案例一致,不在重复描述):

App.js

import React, { Component } from 'react'
import {Route,Switch,Redirect} 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">
							{/* 在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">
								{/* 注册路由 */}
								<Switch>
									<Route path="/about" component={About}/>
									<Route path="/home" component={Home}/>
									<Redirect to="/about"/>
								</Switch>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

运行结果:
在这里插入图片描述

三、路由组件与一般组件的区别

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"
      

代码片段(为节省空间,该案例MyNavLink.jsx、App、Home、index的代码和上述第三个案例一致,不在重复描述):
Header.jsx(一般组件):

import React, { Component } from 'react'

export default class Header extends Component {
	render() {
		console.log('Header组件收到的props是',this.props);
		return (
			<div className="page-header"><h2>React Router Demo</h2></div>
		)
	}
}

About.jsx(路由组件):


import React, { Component } from 'react'

export default class About extends Component {
	render () {
		console.log('About组件收到的props是', this.props);
		return (
			<h3>我是About的内容</h3>
		)
	}
}

运行结果:

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Router 是一个用于在 React 应用中实现路由功能的库。它提供了一种声明式的方式来定义和管理应用程序的路由,使得页面之间的导航和状态管理更加方便和灵活。React Router 的原理可以概括为以下几个关键概念和步骤: 1. **路由器(Router):** React Router 提供了多种类型的路由组件,如 `BrowserRouter`、`HashRouter` 等。路由组件负责监听 URL 的变化,并将相应的路由信息传递给应用程序。 2. **路由规则(Route):** 使用 `Route` 组件来定义路由规则。每个 `Route` 组件负责匹配 URL,并在匹配成功时渲染对应的组件。可以通过 `path` 属性来指定匹配的路径,通过 `component` 属性来指定要渲染的组件。 3. **导航(Navigation):** React Router 提供了多种导航组件来实现页面之间的跳转,如 `Link`、`NavLink` 等。这些导航组件会生成对应的 `<a>` 标签,并处理点击事件来触发路由的变化。 4. **路由参数(Route Parameters):** 可以通过在路由规则中使用冒号(`:`)来定义动态的路由参数,如 `/users/:id`。在匹配成功后,可以通过 `props.match.params` 来获取路由参数的值。 5. **嵌套路由(Nested Routes):** React Router 支持嵌套路由,即在一个组件内部定义子组件路由规则。可以通过嵌套的 `Route` 组件来实现。 6. **路由守卫(Route Guards):** React Router 提供了一些钩子函数,如 `beforeEnter`、`beforeLeave` 等,用于实现路由守卫功能。可以在路由跳转前或跳转后执行一些逻辑操作,例如验证用户权限、处理登录状态等。 总的来说,React Router 的原理是通过路由器监听 URL 的变化,根据定义的路由规则匹配对应的组件进行渲染,同时提供导航组件来实现页面之间的跳转。这样可以实现单页面应用(SPA)的路由功能,使得页面的切换和状态管理更加灵活和可控。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值