React项目之路由:react-router

路由:react-router

什么是路由:路由就是对应关系;

后端路由:URL地址到后端处理函数之间的对应关系;

前端路由:hash地址到组件之间的对应关系; 监听window.onhashchange事件,并拿到最新的hash值,然后对应展示不同的组件即可;

配置React路由

回顾Vue中的路由router

  1. 运行:cnpm i vue-router -S
  2. 创建路由的实例对象 const router = new VueRouter({ routers: [ ] }) 【创建路由规则】
  3. 将new出来的路由实例对象,挂载到VM的router属性上
  4. 在对应的组件中,使用<router-link to="路由地址"></router-link> 【创建路由链接】
  5. 在页面上放一个<router-view></router-view> 【路由组件的容器】

总结:如果在框架中要使用路由,一定要有【路由规则、路由链接、呈现路由组件的容器】


第一步:运行cnpm i react-router-dom -S安装依赖项

第二步:创建一个src/components/App.jsx根组件,并在根组件中,按需导入路由需要的三个组件:

  1. Link 是路由链接
  2. Route 是路由的规则,同时也是路由的容器
  3. HashRouter 表示路由的包裹容器,在一个项目中,只需要使用唯一的一次!!!
注意:HashRouter 必须用作 App 根组件的最外层容器;HashRouter内部,只允许放唯一的一个元素
render(){	
  return <HashRouter>
  	<div>
      <h3>App 根组件</h3>
      <h3>App 根组件</h3>
     </div>
  </HashRouter>
}

创建一个src/components/App.jsx根组件

  1. 创建一个App.jsx根组件,并在根组件中,按需导入路由需要的三个组件:
import { HashRouter, Route, Link } from 'react-router-dom'
  1. App.jsx中,render 函数中,最外层使用HashRouter进行包裹:
render(){
return <HashRouter>
	<div>
  	<h1>大标题</h1>
  </div>
</HashRouter>
}
  1. 在 需要的地方,使用Link组件创建路由链接,其中,通过to属性指定路由地址:
<Link to="/home">首页</Link>
  1. 使用Route组件创建路由规则,同时注意:Route组件有两重身份:
  2. 代表一个路由规则
    • path 表示要匹配的路由规则
    • component 表示要展示的组件
    • exact 精确匹配的路由规则
精确匹配的含义:只有link的to属性完全等于 Route 的 path 的时候,才会展示对应的component 组件

注意:如果Route不设置exact  属性,则默认模糊匹配的路由规则

模糊匹配的含义:把 link 的 to属性 和 Route 的 path ,从 前 到 后 进 行 匹配 

只要 link 的 to 属性中 包含 Route 的 path即可。不一定非要让 to === path

  1. 表示一个路由匹配到的组件呈现的容器;占位符(用来显示匹配到的组件)
// 导入 Home 组件
import Home from './components/Home.jsx'

<Route path="/home" component={Home} exact></Route>

创建一个src/components/App.jsx根组件

import React from 'react'
{/* 导入需要的路由组件*/}
import { HashRouter, Route, Link,Redirect } from 'react-router-dom'

{/* 导入 Home、Movie、About 组件 */}
import Home from '@/components/Home.jsx'
import Movie from '@/components/Movie.jsx'
import About from '@/components/About.jsx'

export default class App extends React.Component {
 constructor(){
     super()
     {/* 组件私有数据 */}
     this.state = {}
	}
 render(){	
     return <HashRouter>
         <div>
             
        <Link to="/home">首页</Link>
        <Link to="/movie/top250">电影</Link>
        <Link to="/about">关于</Link>
        <hr />
        {/* 路由规则 */}
        <Route path="/home"  component={Home}></Route>
        <Route path="/movie/:type" component={Movie}></Route>
        <Route path="/about" component={About}></Route>
        {/* 路由重定向 */}
        <Route exact path="/" render={() => <Redirect to="/home" />}></Route>

       </div>
     </HashRouter>
 }
}

src/components/Home.jsx页面中:

import React from 'react'

export default class Home extends React.Component {
 constructor(){
     super()

     {/* 组件私有数据 */}
     this.state = {}
 }
 render(){	
     return <div>Home内容
         <button onClick={()=>this.goAbout()}>跳转到about页面</button>
     </div>
 }
 goAbout=()=>{
  	this.props.history.push('/about')
 }
}

创建一个src/components/Movie.jsx组件

import React from 'react'

export default class Movie extends React.Component {
 constructor(){
     super()

     {/* 组件私有数据 */}
     this.state = {}
 }

 render(){	
 	return <div>Movie内容---{this.props.match.type}</div>
 }
}

创建一个src/components/About.jsx组件

import React from 'react'

import { Link, Route,Redirect } from 'react-router-dom'

{/*导入 子路由组件*/}
import Tab1 from '@/components/tabs/Tab1'
import Tab2 from '@/components/tabs/Tab2'

export default class About extends React.Component {
 constructor(){
     super()

     {/* 组件私有数据 */}
     this.state = {}
 }
 render(){	
     return <div>
      <button onClick={()=>this.goBack()}>返回上一级页面</button>
      <Link to="/about/tab1">Tab1</Link>&nbsp;&nbsp;
      <Link to="/about/tab2">Tab2</Link>

  {/* 应该对应放置两个 Route 占位符,分别用来显示 匹配到的 路由组件 */}
  {/* 重定向的路由规则 */}
  <Route exact path="/about" render={() => <Redirect to="/about/tab1" />}></Route>
  <Route path="/about/tab1" component={Tab1}></Route>
  <Route path="/about/tab2" component={Tab2}></Route>

     </div>
 }

 goBack() {
  	this.props.history.go(-1)
 }

}

在index.js页面中

import React from 'react'
import ReactDOM from 'react-dom'

{/*导入 App 根组件*/}
import App from '@/components/App'

ReactDOM.render(<App></App>, document.getElementById('app'))

路由重定向(多种方法)

  • 方法一:标签重定向(适用于简单类型)

假设:Home页面重定向到ReHome页面

  1. 首先:新建 Home.js页面 和 ReHome.js页面
  2. 将下面代码放在页面占位区域
<Route path="/ReHome" component={ReHome}></Route>
  1. 在Home.js页面
import { Link,Redirect } from 'react-router-dom'

render() {
       return (
           <div>
               <Redirect to="/ReHome/"></Redirect>
           </div>
       );
   }
  • 方法二:编程式重定向(适用于复杂的业务逻辑)

还是以上面的页面为例,上面的步骤1,2 不变

  1. 在Home.js页面
constructor(props) {
   super(props);
   this.state = {}
   this.props.history.push('/ReHome')
}
  • 方法三:使用render函数

App.jsx根组件中:

  1. 需要按需导入Redirect组件:
import { HashRouter, Route, Link, Redirect } from 'react-router-dom'
  1. 新建一个路由规则
  • exact 属性表示 精确匹配
  • path 表示 重定向之前的 路由规则
  • render 是一个函数,必须 为 render 属性绑定一个 function,因此最佳实践是提供一个 箭头函数
    在 提供的 箭头函数中,需要return 一个 组件,其中, to 属性为 重定向的路由
<Route exact path="/" render={() => <Redirect to="/home" />}></Route>

路由嵌套

react中如何实现路由嵌套:直接在需要的组件页面中,创建属于当前页面的 LinkRoute,那么,这些创建的 RouteLink都属于子路由;

假设about.jsx关于页面需要嵌套两个路由Tab1Tab2

  1. 在about.jsx页面导入需要的路由组件:
import { Link, Route, Redirect } from 'react-router-dom'
  1. 在about.jsx页面导入需要的子路由组件:
    • src/components/tabs/新建Tab1.jsx
    • src/components/tabs/新建Tab2.jsx
// 导入 子路由组件
import Tab1 from '@/components/tabs/Tab1'
import Tab2 from '@/components/tabs/Tab2'
  1. 在about.jsx页面,创建独属于当前页面的子路由链接:
<Link to="/about/tab1">Tab1</Link>&nbsp;&nbsp;
<Link to="/about/tab2">Tab2</Link>
  1. 在about.jsx页面,创建独属于当前页面的子路由规则:
{/* 应该对应放置两个 Route 占位符,分别用来显示 匹配到的 路由组件 */}
{/* 重定向的路由规则 */}
<Route exact path="/about" render={() => <Redirect to="/about/tab1" />}></Route>
<Route path="/about/tab1" component={Tab1}></Route>
<Route path="/about/tab2" component={Tab2}></Route>

获取路由规则中的参数

  1. 需要把路由规则中,对应参数的片段区域,使用:指定为参数:
<Route exact path="/movie/:type/:id" component={Movie}></Route>
  1. 获取 路由规则中匹配到的参数:
this.props.match.params.type

编程式导航

通过 this.props.history对象提供的方法, 可以实现编程式导航:

  1. this.props.history.go(n) 前进或后退N个历史记录
  2. this.props.history.goBack()后退1个历史记录
  3. this.props.history.goForward()前进1个历史记录
  4. this.props.history.push('url地址')跳转到哪个路由超链接中去

路由练习案例:

放在GitHub

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花流雨

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值