🧁个人主页:个人主页
✌支持我 :点赞👍收藏🌼关注🧡
文章目录
- ⛳React 路由
-
- 🔮路由简介
-
- 1.什么是路由
- 2.路由安装
- 🧩路由的使用
-
- (1)路由方法导入
- (2)定义路由
- (3)路由重定向
- (4)嵌套路由
- (5)路由跳转方式
- (6)路由传参
- (7)路由拦截
- (8)路由模式
-
- HashRouter模式
- BrowserRouter模式
- 额外命名
- (9)withRouter
- 🏫项目注意
-
-
- 反向代理
- CSSModule
-
⛳React 路由
🔮路由简介
1.什么是路由
📍路由是根据不同的 url 地址显示不同的内容或页面
📍一个针对React而设计的路由解决方案,可以友好的帮助解决React components到URL之间的同步映射关系
2.路由安装
npm install react-router-dom@5
🧩路由的使用
(1)路由方法导入
import React, { Component } from 'react'
import {HashRouter,Route} from 'react-router-dom'
(2)定义路由
<HashRouter>
<Route path='/films' component={Films}/>
<Route path='/cinemas' component={Cinemas}/>
<Route path='/center'component={Center}>1111</Route>
</HashRouter>
(3)路由重定向
💧1. 会导航到一个新的位置,新的位置将覆盖历史堆栈中的当前条目,例如服务器端重定向
💧2. 当用户访问某界面时,若该界面并不存在,则需跳转到一个我们自定义的界面,此时需要用Redirect重定向
//引入redirect
import {HashRouter,Redirect,Route} from 'react-router-dom'
..................................
<Redirect from='/' to="/films"></Redirect>
💧1. from: string => 要从中进行重定向的路径名
💧2. to:string => 要重定向到的位置
以上为模糊匹配,凡是以/开头的都会跳转到films
解决
引入Switch组件
import {HashRouter,Redirect,Route,Switch} from 'react-router-dom'
....................................
<Switch>
<Route path='/films' component={Films}/>
<Route path='/cinemas' component={Cinemas}/>
<Route path='/center'component={Center}>1
{/* 模糊匹配 凡是以/开头的都会跳转到films*/}
<Redirect from='/' to="/films"></Redirect>
</Switch>
Switch如switch语句一样,若匹配到,则不在匹配;若均未匹配到,则跳转到自定义的界面films
注意:Redirect必须放在Switch里的最后一行,表示上面路由都匹配不到,则跳转到“/films”组件
精准匹配
//语法
<Redirect from='/' to="/films" exact></Redirect>
加上 exact 表示精确匹配,只有完全是"/“时才会跳转到”/films"界面
............................................
<Switch>
<Route path='/films' component={Films}/>
<Route path='/cinemas' component={Cinemas}/>
<Route path='/center'component={Center}>1111</Route>
{/* 模糊匹配 凡是以/开头的都会跳转到films*/}
<Redirect from='/' to="/films"></Redirect>
{/* 精确匹配 */}
<Redirect from='/' to="/films" exact></Redirect>
<Route component={NotFound}></Route>
</Switch>
当输入的路径都不匹配时,则会跳转到 NotFound界面
(4)嵌套路由
//films组件中
<Switch>
<Route path='/films/nowplaying' component={nowplaying}></Route>
<Route path='/films/Comingsoon' component={Comingsoon}></Route>
<Redirect from="/films" to="/films/nowplaying"></Redirect>
</Switch>
(5)路由跳转方式
-
声明式导航
import { NavLink } from 'react-router-dom' <NavLink to="/films" activeClassName='active'>电影</NavLink> <NavLink to="/cinemas" activeClassName='active'>影院</NavLink> <NavLink to="/center" activeClassName='active'>我的</NavLink>
点击时将会跳转到对应的界面,activeClassName属性每次加到被点击的那个标签上,可以通过这个来添加样式
-
编程式导航(注意HOOK使用 类组件不可以直接使用)
-
第一种写法
//被Route包裹时,组件中会获得形参props this.props.history.push(`/center`)
-
第二种写法
import {useHistory} from 'react-router-dom' ...................................... const history = useHistory() const handleChangePage=(id)=>{ history.push(`/detail/${id}`) }
-
(6)路由传参
-
动态路由传参(推荐)
//定义路由 <Route path='/detail/:myid' component={Detail}></Route> //传参 history.push(`/detail/${id}`) //获得参数 props.match.params.myid
其中 ":myid"为占位符(要传的参数),表示路由必须写成 =>/detail/111的格式
页面刷新,参数不会丢失
-
query传参
//定义路由 <Route path='/detail' component={Detail}></Route> //传参 props.history.push({pathname:'/detail',query:{myid:id}}) //获得参数 console.log(props.location.query.myid,'利用id去后端拿数据');
刷新地址栏,参数丢失
-
state传参
//定义路由 <Route path='/detail' component={Detail}></Route> //传参 history.push({pathname:'/detail',state:{myid:id}}) //获得参数 console.log(props.location.state.myid,'利用id去后端拿东西');
使用HashRouter的话,刷新页面,参数会丢失
(7)路由拦截
拦截路由变化做自定义处理,尚未登录时点击观看纪录,则会跳转到登录界面
function isAuth(){
return localStorage.getItem("token")
}
............................................
<Route path='/center' render={()=>{
return isAuth()?<Center/>:<Redirect to="/login"></Redirect>
}}></Route>
判断token,若没有则重定向到“/login”界面
(8)路由模式
HashRouter模式
💧有 # 路径,不像后端发请求要页面
BrowserRouter模式
💧没有 # 的路径,真正向后端发请求要页面,后端没有对对应的路径处理路径,就会404
额外命名
import {BrowserRouter as Router,Redirect,Route,Switch} from 'react-router-dom'
......................................
<Router></Router>
将BrowserRouter/HashRouter,重新命名为Router,方便切换
(9)withRouter
作用
💧将一个组件包裹在Route里面,然后react-router的三个对象history,location,match就会被放进这个组件的props属性中,此时这个组件就有了props,并具备了路由的属性
应用场景
<Route path='/center' render={()=>{
return isAuth()?<Center/>:<Redirect to="/login"></Redirect>
}}></Route>
//组件使用render函数直接渲染,此时组件的this.props为空,无法执行props中的history,location,match方法
💧在层级关系组件中,无法直接获得父组件的props(除传递props外)或 父组件就没有props,此时子组件就无法具备路由的属性
语法
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
function Center(props){
return (
<div>
<div onClick={()=>{
props.history.push(`/filmsorder`)
}}>
</div>
</div>
)
}
export default withRouter(Center)
🏫项目注意
反向代理
前端解决跨域问题
-
在src下创建 setupProxy.js文件
-
安装
npm i http-proxy-middleware
-
setupProxy.js文件中配置反向代理
const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { // app.use(),这个可以配置多个代理 app.use( //ajax是需要转发的请求(所有带有/ajax前缀的请求都会转发给 https://i.maoyan.com) '/ajax', createProxyMiddleware({ //配置转发目标地址(能返回数据的服务器地址) target: 'https://i.maoyan.com', changeOrigin: true, }) ); // https://i.maoyan.com/ajax/mostExpected?limit=10&offset=0&token=&optimus_uuid=C43ACD00C40211EDB6FB1DC502B2262A6C9A830AE637431CBD63E72665CE4A70&optimus_risk_level=71&optimus_code=10
注意:每次编写完setupProxy.js文件后,都要 npm start 重启服务器
-
发送请求
axios({ url:'/ajax/mostExpected?limit=10&offset=0&token=&optimus_uuid=C43ACD00C40211EDB6FB1DC502B2262A6C9A830AE637431CBD63E72665CE4A70&optimus_risk_level=71&optimus_code=10', method:'get' }).then(res=>{ console.log(res.data); })
CSSModule
📍避免所有样式全局剩下,造成样式可能被错误覆盖
📍使用CSS Modules后,样式默认局部
📍对于class选择器、id选择器、以及加了class/id的标签选择器有效(.active ul li{})
-
将css文件名改为 => Film.module.css
-
引入css文件
import style from './css/Film.module.css'
-
<NavLink to="/films/comingsoon" activeClassName={style.zhangsan}> .............................. //css文件中 .zhangsan{ color:green; }
如果想要切换到全局模式
-
定义全局样式
:global(.active){ color:yellow; }
-
定义多个全局样式
:global{ .link{ color:red; } .box{ color:blue; } }