react-router包含3个库,react-router、react-router-dom和react-router-native。
react-router提供最基本的路由功能,实际使⽤的时候我们不会直接安装react-router,⽽是根据应⽤运⾏的环境选择安装react-router-dom(在浏览器中使⽤)或react-router-native(在rn中使⽤)。react-router-dom和react-router-native都依赖react-router,所以在安装时,react-router也会⾃动安装,创建web应⽤
1.安装
npm install --save react-router-dom
2.基本使⽤
react-router中奉⾏⼀切皆组件的思想,路由器-Router、链接-Link、路由-Route、独占-Switch、重定向-Redirect都以组件形式存在
Router:顶层路由组件Router包裹根组件
Link:Link组件编写路由导航
【to】:指定跳转去的路径
Switch:Switch组件表示仅匹配⼀个路由
Route:Route组件编写导航配置
【path】: 配置路径
【component/children/render】: 配置路径所对应的组件或内容
【exact】:完全匹配,只对路径完全一致时才匹配
设定⼀个没有path的路由在路由列表最后⾯,表示⼀定匹配
- 创建RouterPage.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
export default class RouterPage extends Component {
render() {
return (
<div>
<h3>RouterPage</h3>
{/* 引入顶层路由组件Router包裹根组件*/}
<Router>
{/* 引入Link组件编写路由导航 to:指定跳转去的路径*/}
<Link to="/">⾸⻚</Link>
<Link to="/user">⽤户中⼼</Link>
{/* Switch组件表示仅匹配⼀个路由*/}
<Switch>
{/*
引入Route组件编写导航配置
path: 配置路径
component/children/render: 配置路径所对应的组件或内容
exact:完全匹配,只对路径完全一致时才匹配
设定⼀个没有path的路由在路由列表最后⾯,表示⼀定匹配
*/}
<Route
exact
path="/"
component={HomePage}
//children={() => <div>children</div>}
//render={() => <div>render</div>}
/>
<Route path="/user" component={UserPage} />
<Route component={EmptyPage} />
</Switch>
</Router>
</div>
);
}
}
//首页
class HomePage extends Component {
render() {
return (
<div>
<h3>HomePage</h3>
</div>
);
}
}
// ⽤户中⼼
class UserPage extends Component {
render() {
return (
<div>
<h3>UserPage</h3>
</div>
);
}
}
//404
class EmptyPage extends Component {
render() {
return (
<div>
<h3>EmptyPage-404</h3>
</div>
);
}
}
- Route渲染内容的三种⽅式
Route渲染优先级:children>component>render。 这三种⽅式互斥,你只能⽤⼀种。
- children:func
有时候,不管location是否匹配,你都需要渲染⼀些内容,这时候你可以⽤children。除了不管location是否匹配都会被渲染之外,其它⼯作⽅法与render完全⼀样。- render:func
但是当你⽤render的时候,你调⽤的只是个函数。只在当location匹配的时候渲染。- component: component
只在当location匹配的时候渲染。
3.react-router路由传参取参
-
声明式导航路由配置时配置路由参数
// 配置 <Route path="/detail/:id" component={detailPage} /> // 传参 <Link to="/detail/1">⾸⻚</Link> // 获取 结构路由器对象里的macth出来(macth获取参数信息) {macth.params.course}
-
编程式导航路由传参取参
结构路由器对象获取到导航对象history(用作命令式导航) 通过事件执行history.push({patgname:'/',state:{foo:'bar'}})传递的参数挂载在state里面 从路由信息结构出location(当前的url信息)对象location.state进行获取
//首页
function home(props){
const {macth,location,history} = props
return (
<div>
{/*从课程详情页带回来的参数*/}
{location.state.foo}
<Link to="/detail/1">课程详情</Link>
<Route path="/detail/:id" component={detailPage} />
</div>
)
}
//课程详情
function detailPage(props){
const {macth,location,history} = props
return (
<div>
{/*从首页带回来的参数*/}
{macth.params.course}
<button onClick={()=>history.push({patgname:'/',state:{foo:'bar'}})}>返回</button>
</div>
)
}
4.react-router嵌套路由以及路由重定向
// 一级组件
function App(){
return (
<div>
{/*路由导航*/}
<Link to="/mine">我的</Link>
{/*路由配置*/}
<Route path="/mine" component={Mine} />
</div>
)
}
// 二级组件嵌套在一级组件里面进行展示
function Mine(){
return (
<div>
<p>个人中心</p>
{/*路由导航*/}
<Link to="/mine/userinfo">个人信息</Link>
<Link to="/mine/order">绑定手机号</Link>
{/*路由配置*/}
<Route path="/mine/userinfo" component={()=>(<p>个人信息</p>)} />
<Route path="/mine/order" component={()=>(<p>客户订单</p>)} />
{/*重定向*/}
<Redirect to="/mine/order" />
</div>
)
}
嵌套的子路由需要跟随父路由且不设置确切匹配
如:
父路由 /mine
自路由 /mine/xxx
5.路由守卫
路由守卫其实就是我们的路由拦截,当我们有一些项目需要登陆之后才有权限去访问这个时候我们的路由守卫就派上用场啦
React里的路由守卫其实也是一个组件,最后返回的还是Route组件
编写路由守卫组件进行权限控制
//路由守卫组件
class RouteGuard extends Component{
state = {
isLogin:false
}
render(){
const {path,component:Component,...otherProps} = this.poros
return (
<Route
{...otherProps}
render={props=>this.state.isLogin?<Component {...props}/>:<Redirect to={pathname:'/login',state:{from:props.location.pathname}} />)} >
</Route>
)
}
}
// App组件
function App(){
return (
<div>
{/*路由导航*/}
<Link to="/">首页</Link>
<Link to="/mine">我的</Link>
{/*路由配置*/}
<Switch>
<Route exact path="/" component={HomePage}/>
<RouteGuard path="/mine" component={UserPage} />
<Route component={EmptyPage} />
</Switch>
</div>
)
}