目录
1.路由介绍
2.路由使用
3.路由组件和一般组件
4.Switch 单一匹配
5.解决二级路由样式丢失的问题
6.路由精准匹配和模糊匹配
1.路由介绍
路由是根据不同的 URL 地址展示不同的内容或页面,在 SPA 应用中,大部分页面结果不改变,只改变部分内容的使用。一个路由其实就是一个映射关系。
前端路由常见的两种模式:hash和history
hash模式:路由上会有个#号,#后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。使用 Javascript 来对 location.hash 进行赋值,改变 URL 的hash值,每次 hash 值的变化,会触发hashchange 这个事件。然后我们便可以监听hashchange来实现更新页面部分内容的操作。
history模式:使用history模式可以让URL看起来更加友好,更符合传统的URL访问习惯,不会出现#号,更加好看。当用户刷新页面之类的操作时,浏览器会给服务器发送请求,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面(nginx配置try_files重定向到index.html),否则会出现404。HTML5 提供了 History API 来实现 URL 的变化,其中最主要的 API 有以下两个:
history.pushState() 新增一个历史记录
history.replaceState() 直接替换当前的历史记录
2.路由使用
- 安装【npm i react-router-dom@5】
- 引入使用到的一些标签【import{Link,Route}from 'react-router-dom'】
- 编写路由链接【Link,NavLink】
- 注册路由【 <Route path="/home" component={Home}></Route>】
- 路由包裹【ReactDOM.render(<BrowserRouter> <App/> </BrowserRouter>, document.getElementById("root"));】整个 App 组件标签采用 BrowserRouter (或使用HashRouter)标签包裹,这样整个 App 组件都在一个路由器的管理下。
{/* 编写路由链接*/}
<Link to="/home">Home</Link>
<NavLink activeClassName="nav-active" to="/home">Home</NavLink>
<MyNavLink to="/home">Home</MyNavLink> //通过封装把冗长的NavLink上的标签放到组件上去了
NavLink给a标签带上了active属性(高亮设置),通过activeClassName 来修改默认的高亮类名
【MyNavLink组件】
import React, { Component } from 'react'
import { NavLink } from 'react-router-dom/cjs/react-router-dom'
export default class MyNavLink extends Component {
render() {
console.log("MyNavLink接收父组件传值props",this.props);
return (
<NavLink activeClassName="nav-active" {...this.props}></NavLink>
)
}
}
在标签体内写的内容都会成为一个 children 属性,因此我们在调用 MyNavLink 时,在标签体中写的内容,都会成为 props 中的一部分。如下MyNavLink标签内的内容Home会成为props的children属性
<MyNavLink to="/home" a={1} b={2}>Home</MyNavLink>
3.路由组件和一般组件
- 写法不同:一般组件【<Home/>】,路由组件【 <Route path="/home" component={Home} />】
- 存放的位置不同:路由组件放在 pages 文件夹中,一般组件放在 components文件夹中
- 最重要的一点就是它们接收到的 props 不同,在一般组件中,如果我们不进行传递,就不会收到值。而对于路由组件而言,它会接收到 3 个固定属性 history 、location 以及 match
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.Switch 单一匹配
当/about路径匹配上了第一个About 组件后,它还会继续向下匹配Test组件,采用 Switch 组件进行包裹后只进行单一匹配,不会再向下去匹配了,可以提高路由匹配效率。
5.解决二级路由样式丢失的问题
当index.html以相对路径方式引入css文件时,【 <link href="./css/bootstrap.css" rel="stylesheet">】(该文件放在public/css路径下)在如下二级路由的情况下存在刷新页面导致样式丢失的问题。
<MyNavLink to = "/base/about" >About</MyNavLink>
<Route path="/base/about"component={About}/>
http://localhost:3000是webpack内置的服务器,通过devServer开启的。public文件夹相当于是localhost:3000的根路径。
当刷新页面后,获取bootstrap.css文件的请求路径上带了base,并且返回状态码200,请求成功,这是因为请求的资源不存在时,会把index.html响应给该请求,所以状态码为200。
(1)使用绝对路径/
<link href="/css/bootstrap.css" rel="stylesheet">
(2)使用PUBLIC_URL%
<link href="%PUBLIC_URL%/css/bootstrap.css" rel="stylesheet">
(3)使用HashRouter
因为HashRouter会添加#,默认不会处理#后面的路径,所以也是可以解决的
6.路由精准匹配和模糊匹配
模糊匹配可以理解为,在匹配路由时,只要有匹配到的就好了,要求输入的路径必须包含匹配的路径,且顺序要一致
<MyNavLink to = "/home/a/b" >Home</MyNavLink>
<Route path="/home"component={Home}/>
精准匹配:两者必须相同,通过exact开启严格匹配
<Route exact={true} path="/home" component={Home}/>
或者
<Route exact path="/home" component={Home}/>
严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由。