React(五) —— 路由的使用

🧁个人主页:个人主页

✌支持我 :点赞👍收藏🌼关注🧡

⛳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;
        }
    }
    
  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
在前两篇中,我们介绍了 React Router 和路由的基础知识,以及如何在应用中使用路由。在本篇中,我们将深入学习 React Router,并介绍一些更高级的用法。 ## 动态路由 在前面的教程中,我们已经学习了如何定义静态路由。但是在实际开发中,我们通常需要处理动态路由。例如,我们可能需要在 URL 中传递参数,以便根据参数来渲染不同的组件。 在 React Router 中,我们可以使用 `:param` 来定义动态路由参数。例如,我们可以定义一个动态路由 `/user/:id`,其中 `:id` 表示一个动态参数,表示用户的 ID。当浏览器访问 `/user/123` 时,React Router 会自动将 `123` 作为参数传递给对应的组件。 下面是一个简单的例子: ```jsx import { BrowserRouter as Router, Route, Link } from "react-router-dom"; function User({ match }) { return <h1>Hello, {match.params.id}!</h1>; } function App() { return ( <Router> <div> <ul> <li> <Link to="/user/123">User 123</Link> </li> <li> <Link to="/user/456">User 456</Link> </li> </ul> <Route path="/user/:id" component={User} /> </div> </Router> ); } ``` 在上面的例子中,我们定义了一个动态路由 `/user/:id`,其中 `:id` 表示用户的 ID。当浏览器访问 `/user/123` 时,React Router 会自动将 `123` 作为参数传递给 `User` 组件,并显示 `Hello, 123!`。 同样,当浏览器访问 `/user/456` 时,React Router 会自动将 `456` 作为参数传递给 `User` 组件,并显示 `Hello, 456!`。 ## 嵌套路由 在实际开发中,我们经常需要在一个页面中嵌套多个组件。在 React Router 中,我们可以使用嵌套路由来实现这个功能。 具体来说,我们可以在一个组件中定义多个 `<Route>` 组件,从而实现嵌套路由。例如,我们可以定义一个嵌套路由 `/user/:id/posts`,其中 `:id` 表示用户的 ID,`posts` 表示用户的帖子列表。 下面是一个简单的例子: ```jsx import { BrowserRouter as Router, Route, Link } from "react-router-dom"; function User({ match }) { return ( <div> <h1>Hello, {match.params.id}!</h1> <ul> <li> <Link to={`${match.url}/posts`}>Posts</Link> </li> </ul> <Route path={`${match.path}/posts`} component={Posts} /> </div> ); } function Posts() { return <h2>Posts</h2>; } function App() { return ( <Router> <div> <ul> <li> <Link to="/user/123">User 123</Link> </li> <li> <Link to="/user/456">User 456</Link> </li> </ul> <Route path="/user/:id" component={User} /> </div> </Router> ); } ``` 在上面的例子中,我们定义了一个嵌套路由 `/user/:id/posts`,其中 `:id` 表示用户的 ID,`posts` 表示用户的帖子列表。当浏览器访问 `/user/123/posts` 时,React Router 会自动将 `123` 作为参数传递给 `User` 组件,并显示 `Posts` 组件。 ## 路由守卫 在实际开发中,我们通常需要实现一些路由守卫功能,例如登录验证、权限控制等。在 React Router 中,我们可以使用 `Route` 组件的 `render` 属性来实现路由守卫。 具体来说,我们可以定义一个高阶组件 `AuthRoute`,用来检查用户是否登录。如果用户已登录,则渲染对应的组件;否则,跳转到登录页面。 下面是一个简单的例子: ```jsx import { BrowserRouter as Router, Route, Link, Redirect } from "react-router-dom"; function AuthRoute({ component: Component, ...rest }) { const isAuthenticated = localStorage.getItem("isAuthenticated"); return ( <Route {...rest} render={(props) => isAuthenticated ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: "/login", state: { from: props.location } }} /> ) } /> ); } function Home() { return <h1>Welcome Home!</h1>; } function Login() { const login = () => { localStorage.setItem("isAuthenticated", true); }; return ( <div> <h2>Login</h2> <button onClick={login}>Login</button> </div> ); } function App() { return ( <Router> <div> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/login">Login</Link> </li> </ul> <AuthRoute exact path="/" component={Home} /> <Route path="/login" component={Login} /> </div> </Router> ); } ``` 在上面的例子中,我们定义了一个高阶组件 `AuthRoute`,用来检查用户是否登录。如果用户已登录,则渲染对应的组件;否则,跳转到登录页面。具体来说,我们首先从本地存储中检查用户是否已登录,然后根据检查结果来渲染对应的组件或跳转到登录页面。 ## 总结 在本篇教程中,我们深入学习了 React Router,并介绍了一些更高级的用法。具体来说,我们学习了如何定义动态路由、嵌套路由路由守卫。 希望通过本篇教程,你已经掌握了 React Router 的高级用法,并能够在实际开发中灵活使用

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值