路由:react-router
什么是路由:路由就是对应关系;
后端路由:URL地址到后端处理函数之间的对应关系;
前端路由:hash地址到组件之间的对应关系; 监听
window.onhashchange
事件,并拿到最新的hash值,然后对应展示不同的组件即可;
配置React路由
回顾Vue中的路由router
- 运行:
cnpm i vue-router -S
- 创建路由的实例对象 const router = new VueRouter({ routers: [ ] }) 【创建路由规则】
- 将new出来的路由实例对象,挂载到VM的router属性上
- 在对应的组件中,使用
<router-link to="路由地址"></router-link>
【创建路由链接】- 在页面上放一个
<router-view></router-view>
【路由组件的容器】总结:如果在框架中要使用路由,一定要有【路由规则、路由链接、呈现路由组件的容器】
第一步:运行
cnpm i react-router-dom -S
安装依赖项第二步:创建一个
src/components/App.jsx
根组件,并在根组件中,按需导入路由需要的三个组件:
- Link 是路由链接
- Route 是路由的规则,同时也是路由的容器
- HashRouter 表示路由的包裹容器,在一个项目中,只需要使用唯一的一次!!!
注意:HashRouter 必须用作
App 根组件
的最外层容器;HashRouter内部,只允许放唯一的一个元素render(){ return <HashRouter> <div> <h3>App 根组件</h3> <h3>App 根组件</h3> </div> </HashRouter> }
创建一个src/components/App.jsx
根组件
- 创建一个
App.jsx
根组件,并在根组件中,按需导入路由需要的三个组件:import { HashRouter, Route, Link } from 'react-router-dom'
- 在
App.jsx
中,render 函数中,最外层使用HashRouter
进行包裹:render(){ return <HashRouter> <div> <h1>大标题</h1> </div> </HashRouter> }
- 在 需要的地方,使用
Link
组件创建路由链接,其中,通过to
属性指定路由地址:<Link to="/home">首页</Link>
- 使用
Route
组件创建路由规则,同时注意:Route组件有两重身份:- 代表一个路由规则
- path 表示要匹配的路由规则
- component 表示要展示的组件
- exact 精确匹配的路由规则
精确匹配的含义:只有link的to属性完全等于 Route 的 path 的时候,才会展示对应的component 组件 注意:如果Route不设置exact 属性,则默认模糊匹配的路由规则 模糊匹配的含义:把 link 的 to属性 和 Route 的 path ,从 前 到 后 进 行 匹配 只要 link 的 to 属性中 包含 Route 的 path即可。不一定非要让 to === path
- 表示一个路由匹配到的组件呈现的容器;占位符(用来显示匹配到的组件)
// 导入 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> <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页面
- 首先:新建 Home.js页面 和 ReHome.js页面
- 将下面代码放在页面占位区域
<Route path="/ReHome" component={ReHome}></Route>
- 在Home.js页面
import { Link,Redirect } from 'react-router-dom' render() { return ( <div> <Redirect to="/ReHome/"></Redirect> </div> ); }
- 方法二:编程式重定向(适用于复杂的业务逻辑)
还是以上面的页面为例,上面的步骤1,2 不变
- 在Home.js页面
constructor(props) { super(props); this.state = {} this.props.history.push('/ReHome') }
- 方法三:使用render函数
在
App.jsx
根组件中:
- 需要按需导入
Redirect
组件:import { HashRouter, Route, Link, Redirect } from 'react-router-dom'
- 新建一个路由规则
- exact 属性表示 精确匹配
- path 表示 重定向之前的 路由规则
- render 是一个函数,必须 为 render 属性绑定一个 function,因此最佳实践是提供一个 箭头函数
在 提供的 箭头函数中,需要return 一个 组件,其中, to 属性为 重定向的路由<Route exact path="/" render={() => <Redirect to="/home" />}></Route>
路由嵌套
react中如何实现路由嵌套:直接在需要的组件页面中,创建属于当前页面的
Link
和Route
,那么,这些创建的Route
和Link
都属于子路由;假设
about.jsx关于页面
需要嵌套两个路由Tab1
和Tab2
在about.jsx页面
导入需要的路由组件:import { Link, Route, Redirect } from 'react-router-dom'
在about.jsx页面
导入需要的子路由组件:
src/components/tabs/新建Tab1.jsx
src/components/tabs/新建Tab2.jsx
// 导入 子路由组件 import Tab1 from '@/components/tabs/Tab1' import Tab2 from '@/components/tabs/Tab2'
在about.jsx页面
,创建独属于当前页面的子路由链接:<Link to="/about/tab1">Tab1</Link> <Link to="/about/tab2">Tab2</Link>
在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>
获取路由规则中的参数
- 需要把路由规则中,对应参数的片段区域,使用
:
指定为参数:<Route exact path="/movie/:type/:id" component={Movie}></Route>
- 获取 路由规则中匹配到的参数:
this.props.match.params.type
编程式导航
通过
this.props.history
对象提供的方法, 可以实现编程式导航:
this.props.history.go(n)
前进或后退N个历史记录this.props.history.goBack()
后退1个历史记录this.props.history.goForward()
前进1个历史记录this.props.history.push('url地址')
跳转到哪个路由超链接中去
路由练习案例:
放在
GitHub
上