下载 npm install react-router-dom(第四代版本开始)
官网 https://reacttraining.com/react-router/
路由器 Routers
- import { BrowserRouter , HashHistory ,Switch, Route, Link, Redirect, useParams } from "react-router-dom";
- BrowserRouter 路由不带#,需要配置 响应请求服务
- HashHistory 路由带# 静态文件服务
- 注:两者都只能有一个一级节点,且都会为你创建一个特有的history
- Route 设置路由规则
- Redirect 重定向
- exact 严格匹配
- Switch 当找到相对应的,则不会继续匹配
路由规则:
1.与vue路由不同 如果不用则会继续往下匹配路由 则需要用Switch
2.默认匹配规则不精准且不严格,路由/ab =》 path='/' path='/ab' 匹配 包含地址规则 则需要用到exact
import {BrowserRouter,Switch,Route,Redirect} from "react-router-dom";
<HashRouter>
<Switch>
<Route path='/' exact component={A}></Route>
<Route path='/a' component={B}></Route>
<Route path='/b' component={C}></Route>
<Redirect from='/' to='/b' exact> //from从哪来 to去哪里
<Route to='*' component={error}>//*剩下所有,以上规则都不符合 404
</Switch>
</HashRouter>
路由跳转 Link与NavLink区别:
Link:
<Link to={{
pathname: '跳转地址',
search: '?跳转地址',
hash: '#跳转地址',
state: { fromDashboard: true }
}}/>
NavLink在Link基础上增加了:
-
activeClassName(string):设置选中样式
-
activeStyle(object):当元素被选中时样式
-
exact(bool):为true时,严格匹配
-
strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线
-
isActive(func) 路由匹配自定义
const oddEvent = (match, location) => {
// return alert()
}
<NavLink to='/aa' exact activeStyle={{ fontWeight: "bold", color: "red" }} activeClassName="selected" isActive={oddEvent}>子路由1</NavLink>
导航式路由跳转:
<NavLink to={{ pathname: "/other", state: { 'id': 123, "canshuB": true } }} > state传参</NavLink> {/* this.props.location.state接收参数 */}
方法式路由跳转:
//接收参数this.props.location
this.props.history.push({
pathname: "/a",
search:'?a=10',//问好传参,要求是必须字符串
hash:'#a',
state:{ //隐性传参,页面刷新后传递的信息没有
n:100
},
query: {
'id': 2,
"canshuB": true,
}
});
不受路由管控的组件默认就没有history和localtion 例如导航组件等
使用withRouter 注:组件必须放在HashRouter或者BroweRouter
import { withRouter} from 'react-router-dom'
class AA extends Component{
render() {
return (
<div>组件</div>
)
}
}
export defalut withRouter(AA)
二级路由
<Switch>
<Route path="/:id" children={<Child />} />
<Redirect to='/aa'></Redirect>
</Switch>
完整代码块测试:两个js文件1 APP.js 2 First.js
APP.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import First from './First'
import {
BrowserRouter as Router,
Switch,
Route,
Link, Redirect, useParams
} from "react-router-dom";
class Two extends Component {
render() {
return (
<div>我是第二个</div>
)
}
}
class Three extends Component {
render() {
return (
<div>我是第三个</div>
)
}
}
const Four = () => {// 函数方式
return (<div>第四个</div>)
}
class Other extends Component {
render() {
console.log(this.props)
return (
<div>跳转传参</div>
)
}
}
class APP extends Component {
render() {
return (
<div>
<Router>
{/* 只允许放一个跟标签 */}
<div>
<Link to='/' >第一个</Link>
<Link to='/a'>第二个</Link>
<Link to='/b'>第三个</Link>
<Link to='/c'>第四个</Link>
{/* search: "?other" */}
{/* hash: "#other" */}
<Link to={{
pathname: '/other',
search: 'other',
hash: 'other',
}}>跳转传参</Link>
</div>
<Route exact path='/' component={First} name="First"></Route> {/* exact严格匹配 */}
<Route path='/a' component={Two}></Route>
<Route path='/b' component={Three}></Route>
<Route path='/c' component={Four}></Route>
<Route path='/other' component={Other}></Route>
<Route path="/" render={
() => (
<Redirect to="/" />)}> {/* 重定向 */}
</Route>
</Router>
</div>
)
}
}
export default APP;
First.js
import React, { Component } from 'react';
import './App.css';
import {
BrowserRouter as Router,
Switch,
Route,
Link, Redirect, useParams, NavLink
} from "react-router-dom";
export default class First extends Component {
bth() {
// pathname为路径 query为一个对象 this.props.location.query接收参数
this.props.history.push({
pathname: "/other", query: {
'id': 123,
"canshuB": true,
}
});
}
bthstate() {
// this.props.location.state 接收参数
// 刷新后不会丢失
this.props.history.push({
pathname: "/other", state: {
'id': 123,
"canshuB": true,
}
});
}
bthparams() {
this.props.history.push({
pathname: "/other", params: {
'id': 123,
"canshuB": true,
}
});
}
// replace与push 前者不进入记录
bthreplace() {
this.props.history.push({
pathname: "/other", params: {
'id': 123,
"canshuB": true,
}
});
}
render() {
const oddEvent = (match, location) => {
// return alert()
}
return (
<Router>
<div>
{/* activeClassName:string 激活时,显示类名为selected 的css样式 */}
{/* activeStyle:object 处于活动状态时应用于该元素的样式 */}
{/* exact: 精确匹配 */}
{/* isActive: :function 不仅仅可以验证路由是否匹配 */}
<NavLink to='/aa' exact activeStyle={{ fontWeight: "bold", color: "red" }} activeClassName="selected" isActive={oddEvent}>子路由1</NavLink>
<NavLink to='/bb'>子路由2</NavLink>
<NavLink to={{ pathname: "/other", state: { 'id': 123, "canshuB": true } }} > state传参</NavLink> {/* this.props.location.state接收参数 */}
{/* Switch当找到相对应的,则不会继续匹配 */}
<Switch>
<Route path="/:id" children={<Child />} />
<Redirect to='/aa'></Redirect>
</Switch>
<button onClick={this.bth.bind(this)}>push跳转传参</button>
<button onClick={this.bthstate.bind(this)}>pushstate跳转传参</button>
<button onClick={this.bthparams.bind(this)}>pushparams跳转传参</button>
<br />
<button onClick={this.bthreplace.bind(this)}>replace跳转传参</button>
</div>
</Router >
)
}
}
function Child() {
let { id } = useParams();
return (
<div>
<h3 >ID: {id}</h3>
</div>
);
}