1 entendimiento relacionado
1.1 Comprensión de SPA
Aplicación web de una sola página (aplicación web de una sola página, SPA)
Solo hay una página completa para toda la aplicación.
Hacer clic en el enlace de la página no actualizará la página, solo una actualización parcial de la página
Todos los datos deben obtenerse a través de solicitudes ajax y mostrarse de forma asíncrona en el front-end
1.2 Comprensión del enrutamiento
que es el enrutamiento
Una ruta es una relación de mapeo (clave: valor)
la clave es la ruta, el valor puede ser una función o un componente
clasificación de enrutamiento
enrutamiento de back-end
- Comprensión: el valor es una función, utilizada para procesar la solicitud enviada por el cliente
- Registro de enrutamiento: router.get(path, function(req, res))
- Proceso de trabajo: cuando el nodo recibe una solicitud, encuentra la ruta correspondiente de acuerdo con la ruta de la solicitud, llama a la función en la ruta para procesar la solicitud y devuelve los datos de respuesta
enrutamiento de front-end
- Enrutamiento del lado del navegador, el valor es componente, se usa para mostrar el contenido de la página
- Registrar ruta:
<Route path="/test" component={Test}>
- Proceso de trabajo: cuando la ruta del navegador cambia a /prueba, el componente de enrutamiento actual se convertirá en un componente de prueba
1.3 Comprensión de react-router-dom
Conceptos relacionados
-
Una biblioteca de complementos para reaccionar.
-
Específicamente utilizado para implementar una aplicación SPA
-
Los proyectos basados en React básicamente usarán esta biblioteca
API relacionadas
componentes integrados
<BrowserRouter>
<HashRouter>
<Route>
<Redirect>
<Link>
<NavLink>
<Switch>
otro
-
objeto de la historia
-
objeto de coincidencia
-
con función de enrutador
2 Uso básico del enrutamiento
1. Defina el área de navegación y el área de visualización en la interfaz
2. Cambie la etiqueta en el área de navegación a la etiqueta Enlace
<Link to="/xxxxx">Demo</Link>
3. Escriba la etiqueta de ruta en el área de visualización para que coincida con la ruta
<Route path='/xxxx' component={
Demo}/>
4. <App>
La parte exterior del paquete envuelve un<BrowserRouter>或<HashRouter>
//路由编写和路由注册都靠一个BrowserRouter去管理,所以BrowserRouter写外侧,一直扩
//还有一种就是BrowserRouter写在入口文件中,包住App就可以
ReactDOM.render(
<BrowserRouter><App/></BrowserRouter>,
document.getElementById('root')
)
Detalles: el enlace finalmente se convierte en una etiqueta en el navegador
3 Componentes de enrutamiento y componentes generales
escrito de manera diferente
Componentes generales:<Demo/>
Componente de enrutamiento:<Route path="/demo" component={Demo}/>
La ubicación de almacenamiento es diferente
Componentes generales: componentes
Componente de enrutamiento: páginas
Los accesorios recibidos son diferentes.
Componentes generales: lo que se pasa al escribir etiquetas de componentes, lo que se puede recibir
Componente de enrutamiento: recibió tres atributos fijos pasados por el enrutador
//路由属性打印结果展示
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"
Etiqueta de enlace, no se puede agregar un estilo de resaltado, use la versión actualizada de Enlace:
4 Uso y presentación de NavLink
NavLink puede
实现路由链接的高亮
, a través deactiveClassName指定样式名
El resaltado predeterminado está activo, que resulta ser el mismo que el nombre de la clase de estilo de arranque. También podemos especificar el estilo nosotros mismos (el peso es mayor que el de bootstrap)
.NavTitle {
background-color: rgb(183, 238, 119) !important;
color: #fff !important;
}
<NavLink activeClassName='NavTitle' className="list-group-item" to='/about'>About</NavLink>
<NavLink activeClassName='NavTitle' className="list-group-item" to='/home'>Home</NavLink>
Si lo escribes como arriba, sientes que hay muchas repeticiones, así que puedes resumirlo:
Encapsular MyNavLink (componente general)
props se usa para pasar atributos de etiquetas, ¡cómo recibir el contenido del cuerpo de la etiqueta!
Punto clave: el contenido del cuerpo de la etiqueta es en realidad un atributo especial, pero solo podemos escribir el valor, y la clave son los elementos secundarios especificados por otros, por lo que en realidad no podemos escribir el contenido del cuerpo de la etiqueta y luego configurarlo a través del atributo de etiqueta de niños
//封装示例
export default class MyNavLink extends Component {
render() {
return (
/* 注意:这里也把标签体内容带过去了,在children属性里面 */
<NavLink activeClassName="NavTitle" className="list-group-item" {
...this.props}/>
)
}
}
//使用--标签体内容直接写,props会帮我们收集到children标签属性里面
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>
5 Uso del interruptor
Por lo general, la ruta y el componente tienen una correspondencia uno a uno
Pero si hay dos caminos idénticos, que coinciden con dos componentes diferentes, queremos que termine después del primero (para mejorar la eficiencia)
El interruptor puede mejorar la eficiencia de coincidencia de enrutamiento (coincidencia única), es decir, después de hacer coincidir uno, ya no coincidirá.
<Switch>
<Route path="/about" component={
About}/>
<Route path="/home" component={
Home}/>
<Route path="/home" component={
Test}/>
</Switch>
6 Resuelva el problema de que se pierde el estilo de página de actualización de ruta de varios niveles
porque esta perdido
Al escribir enrutamiento multinivel, se perderá después de actualizar la página. El navegador tratará el nivel anterior de enrutamiento como si estuviera en la carpeta pública, y el resultado devuelto por la ruta incorrecta será cubierto por index.html
tres soluciones
No escriba ./write/ (comúnmente utilizado) al introducir estilos en public/index.html
No escriba ./write al introducir estilos en public/index.html %PUBLIC_URL%
(comúnmente usado, pero 只在react中
efectivo)
Use HashRouter (no se usa comúnmente), # detrás están los recursos de front-end, no llevados al servidor
<!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 Coincidencia estricta y difusa de rutas
La ruta dada es /home, pero lo que otros quieren es /home/a/b, que no coincide
La ruta proporcionada es /home/a/b, lo que la gente quiere es /home, coincidencia: coincidencia parcial
La ruta dada es /a/home/b, lo que otros quieren es /home, que no coincide
coincidencia aproximada
El valor predeterminado es la coincidencia aproximada (nota simple: [Ruta de entrada] debe contener [Ruta de coincidencia] más pero no menos, y el orden debe ser coherente)
coincidencia estricta
Habilitar coincidencia estricta: <Route exact={true}
path="/about" component={About}/>, que se puede omitir exact={true}
comoexact
Nota: 严格匹配不要随便开启
debe volver a abrirlo, a veces hará que sea imposible continuar para coincidir con la ruta secundaria
//编写路由链接
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home/a/b">Home</MyNavLink>
{
/* 注册路由 */}
<Switch>
<Route exact path="/about" component={
About}/>
<Route exact path="/home" component={
Home}/>
</Switch>
8 Uso de redirección
Si quieres subir en la página, por favor ayúdame a elegir uno.
Generalmente, está escrito en todos los registros de ruta 最下方
. Cuando todas las rutas están registradas 无法匹配时
, salta a la ruta especificada por Redirección.
<Switch>
<Route path="/about" component={
About}/>
<Route path="/home" component={
Home}/>
<Redirect to="/about"/>
</Switch>
9 Enrutamiento anidado
Al registrar una ruta secundaria, escriba el valor de la ruta de la ruta principal
Las rutas se emparejan en el orden en que se registran
-------------------注册一级路由-----------------------------
{
/* 在React中靠路由链接实现切换组件--编写路由链接 */}
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>
{
/* 注册路由 */}
<Switch>
<Route path="/about" component={
About}/>
<Route path="/home" component={
Home}/>
<Redirect to="/about"/>
</Switch>
----------------------注册二级路由 :Home组件-----------------------------------
<div>
<ul className="nav nav-tabs">
<li>
<MyNavLink to="/home/news">News</MyNavLink>
</li>
<li>
<MyNavLink to="/home/message">Message</MyNavLink>
</li>
</ul>
{
/* 注册路由 */}
<Switch>
<Route path="/home/news" component={
News}/>
<Route path="/home/message" component={
Message}/>
<Redirect to="/home/news"/>
</Switch>
</div>
10 Pasar parámetros a componentes de enrutamiento
10.1 parámetro parámetro
Enlace de enrutamiento (parámetros portadores):<Link to='/demo/test/tom/18'}>详情</Link>
Registrar ruta (declarar recibir):<Route path="/demo/test/:name/:age" component={Test}/>
Los parámetros recibidos tienen parámetros:this.props.match.params
-------------------------------发送参数:父组件----------------------------------------------
<div>
{
/* 向路由组件传递params参数 */}
<Link to={
`/home/message/detail/${
msgObj.id}/${
msgObj.title}`}>{
msgObj.title}</Link>
<hr />
{
/* 声明接收params参数 */}
<Route path="/home/messages/detail/:id/:title" component={
Detail} />
</div>
--------------------------------接受参数:子组件-----------------------------------------------------------
const {
id,title} = this.props.match.params
10.2 parámetros de búsqueda
Enlace de enrutamiento (parámetros portadores):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
Registro de enrutamiento ( 无需声明
, el registro normal es suficiente):<Route path="/demo/test" component={Test}/>
Parámetros de recepción: this.props.location.search
(no organizados en forma de objeto para nosotros)
Observaciones: La búsqueda obtenida es urlencoded编码字符串
obligatoria借助qs库解析
Nota: Dado que la búsqueda no nos ayudó a procesarlo en forma de objeto cuando lo recibimos, necesitamos usar la biblioteca en reaccionar para procesarlo. La nueva versión de la biblioteca es diferente a la anterior.import qs from 'qs'
name=tom&age=18 Este formulario de codificación se denomina formulario de codificación urlencoded
Objeto a urlencoded:qs.stringify(obj)
objeto de conversión con código urlen:qs.parse(str)
-------------------------------发送参数:父组件----------------------------------------------
<div>
{
/* 向路由组件传递search参数 */}
<Link to={
`/home/message/detail/?id=${
msgObj.id}&title=${
msgObj.title}`}>{
msgObj.title}</Link>
<hr />
{
/* search参数无需声明接收,正常注册路由即可 */}
<Route path="/home/messages/detail" component={
Detail}/>
</div>
--------------------------------接受参数:子组件-----------------------------------------------------------
import qs from 'qs'
// 接收search参数
const {
search} = this.props.location
const {
id,title} = qs.parse(search.slice(1))
10.3 parámetro de estado
Los parámetros en la barra de direcciones son invisibles, pero los datos de actualización no se perderán, porque actualmente estamos usando BrowserRouter y hemos estado operando el historial del navegador (la ubicación es un atributo en el historial, que no se perderá; si el historial se borra, se perderá)
Enlace de enrutamiento (parámetros portadores): <Link to={
{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
, to se escribe como un objeto
Registre el enrutamiento (no es necesario declararlo, solo regístrese normalmente):<Route path="/demo/test" component={Test}/>
Recibir parámetros:this.props.location.state
BrowserRouter
Observaciones: solo use actualizar, y el estado no guardará los parámetros después de保留住参数
usarHashRouter
actualizarhistory
- Cuando el subcomponente acepte parámetros
const {id,title} = this.props.location.state || {}
, agréguelo más tarde||{}
para evitarHashRouter
que el estado sea indefinido e informe un error después de su uso.
-------------------------------发送参数:父组件----------------------------------------------
<div>
{
/* 向路由组件传递state参数 */}
<Link to={
{
pathname:'/home/messages/detail',state:{
id:msgObj.id,title:msgObj.title}}}>{
msgObj.title}</Link>
<hr />
{
/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={
Detail}/>
</div>
--------------------------------接受参数:子组件-----------------------------------------------------------
// 接收state参数,后面添加`||{}`是防止使用`HashRouter`后state为undefined时报错
const {
id,title} = this.props.location.state || {
}
11 empujar y reemplazar
push es una operación push, que dejará un registro histórico. replace es una operación de reemplazo que reemplaza el elemento superior de la pila con el elemento actual.
modo push: el modo push está activado de forma predeterminada
modo de reemplazo: replace={true}
, que se puede abreviar comoreplace
<Link replace={
true} to={
{
pathname: '/home/messages/detail', state: {
id: msgObj.id, title: msgObj.title } }}>{
msgObj.title}</Link>
12 Navegación de enrutamiento programático
Hay un requisito: espere 3 segundos para el salto de enrutamiento automático, lo cual es difícil de lograr con la ayuda de Link y NavLink
借助this.prosp.history对象上的API对
Operación enrutamiento salto, adelante, atrás
this.prosp.history.push()
Empuje la historia en la pila
this.props.history.replace()
Ubicación de pila alternativa, es decir, no se generará ningún historial
this.props.history.goBack()
Retrocede un espacio
this.props.history.goForward()
avanzar un espacio
this.props.history.go()
Adelante o atrás n espacios (positivo o negativo según el número entrante)
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' },
]
}
replaceShow = (id, title) => {
//replace跳转+携带params参数
//this.props.history.replace(`/home/message/detail/${id}/${title}`)
//replace跳转+携带search参数
// this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
//replace跳转+携带state参数
this.props.history.replace(`/home/message/detail`, {
id, title })
}
pushShow = (id, title) => {
//push跳转+携带params参数
// this.props.history.push(`/home/message/detail/${id}/${title}`)
//push跳转+携带search参数
// this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)
//push跳转+携带state参数
this.props.history.push(`/home/message/detail`, {
id, title })
}
back = () => {
this.props.history.goBack()
}
forward = () => {
this.props.history.goForward()
}
go = () => {
this.props.history.go(-2)
}
render() {
const {
messageArr } = this.state
return (
<div>
<ul>
{
messageArr.map((msgObj) => {
return (
<li key={
msgObj.id}>
{
/* 向路由组件传递params参数 */}
{
/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}
{
/* 向路由组件传递search参数 */}
{
/* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}
{
/* 向路由组件传递state参数 */}
<Link to={
{
pathname: '/home/message/detail', state: {
id: msgObj.id, title: msgObj.title } }}>{
msgObj.title}</Link>
<button onClick={
() => this.pushShow(msgObj.id, msgObj.title)}>push查看</button>
<button onClick={
() => this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button>
</li>
)
})
}
</ul>
<hr />
{
/* 声明接收params参数 */}
{
/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}
{
/* search参数无需声明接收,正常注册路由即可 */}
{
/* <Route path="/home/message/detail" component={Detail}/> */}
{
/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={
Detail} />
<button onClick={
this.back}>回退</button>
<button onClick={
this.forward}>前进</button>
<button onClick={
this.go}>go</button>
</div>
)
}
}
//记得detail组件中也要响应修改接收的参数形式
//news组件中用编程式路由导航控制路由跳转
componentDidMount() {
setTimeout(() => {
this.props.history.push('/home/messages')
}, 2000)
}
13 Uso de withRouter
withRouter puede procesar componentes generales, de modo que los componentes generales tengan API únicas para los componentes de enrutamiento
El valor de retorno de withRouter es un nuevo componente
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>
<button onClick={
this.forward}>前进</button>
<button onClick={
this.go}>go</button>
</div>
)
}
}
export default withRouter(Header)
14 Diferencia entre BrowserRouter y HashRouter
El principio del enrutamiento front-end es: al hacer clic en el enlace de enrutamiento, la ruta cambia, el enrutador lo detecta y los múltiples clics dejan un registro histórico.
Nota: HashRouter se puede usar para resolver algunos problemas relacionados con errores de ruta. Es decir,
问题6
es posible que la modificación de la ruta no se realice al importar archivos en
14.1 Los principios subyacentes son diferentes
BrowserRouter usa la API de historial de H5, que no es compatible con IE9 e inferior
但一般来说都用的这个
HashRouter usa el valor hash de la URL
14.2 la expresión de ruta es diferente
No hay # en la ruta de BrowserRouter, por ejemplo: localhost:3000/demo/test
La ruta de HashRouter contiene #, por ejemplo: localhost:3000/#/demo/test
14.3 El impacto en los parámetros de estado de enrutamiento después de la actualización
BrowserRouter no tiene efecto porque el estado se almacena en el objeto de historial
HashRouter 刷新后会导致路由state参数的丢失!!!
, porque HashRouter no usa la API de historial