文章目录
引入react-router-dom
官方文档----https://reacttraining.com/react-router/web/example/basic
- 下载
react-router-dom包
npm install react-router-dom --save
- 引入包
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
路由的基本使用
import { BrowserRouter as Router, Route, Link, HashRouter } from "react-router-dom";
...
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
</Switch>
</div>
</Router>
BrowserRouter 和 HashRouter 路由器
老浏览器提供的 hash模式, 我们称之为: HashRouter。H5提供的的 history 模式,我们称之为 BrowserRouter
注意:
HashRouter和BrowserRouter路由器必须要包裹住所有的路由组件
一般我们会在项目的入口文件index.js中包裹项目的根组件App.js,保证HashRouter和BrowserRouter可以包裹所有的路由组件。如下:
ReactDOM.render(
// 用路由器将项目根组件 App 包裹住,保证路由器正常包裹所有的路由组件
<HashRouter>
<App />
</HashRouter>,
document.getElementById('root')
);
route 路由与 Redirect 重定向路由
route 组件表示配置一条路由。如下:
<Route path="/list" component={List} exact></Route>
其中:
path:匹配路由component:匹配路由后要展示的组件exact:路由精准匹配
Redirect组件表示路由重定向。当页面匹配不到路由时,会使用重定向路由。如下:
<!-- 重定向到 /home 路由 -->
<Redirect to="/home" />
注意:
Redirect重定向路由一定要放在路由表的最后
Switch 路由只匹配一次
Switch组件包裹住的路由只匹配一次。如下:
<Switch>
<Route path = "/" component = {Home} exact></Route>
<Route path = "/home" component = {Home}></Route>
<Route path = "/mine" component = {Mine} ></Route>
<Route path = "/mine/login" component = {Login} exact ></Route>
<Redirect to="/home/page1" />
</Switch>
当路由为 /mine时,会匹配到/mine路由,Mine 组件。之后就不会再进行匹配,也就是说,/mine/login不会被匹配到,也就不会展示Login组件。
Link 和 NavLink
Link和NavLink组件会被渲染为a标签。如下:
<ul>
<li>
<NavLink activeClassName="active" to="/">Home</NavLink>
</li>
<li>
<NavLink activeClassName="active" to="/about">About</NavLink>
</li>
<li>
<NavLink activeClassName="active" to="/about/aaa">Dashboard</NavLink>
</li>
</ul>
NavLink组件在路由激活时可以用activeClassName来添加active类名。而Link组件则没有。
路由组件与一般组件的区别
- 写法不同:
<!-- 一般组件 -->
<Demo/>
<!-- 路由组件 -->
<Route path="/demo" component={Demo}/>
- 接收到的props不同:
// 一般组件:写组件标签时传递了什么,就能收到什么
// 路由组件:接收到三个固定的属性 console.log(this.props)
history:
go: ƒ go(n)
goBack: ƒ goBack()
goForward: ƒ goForward()
push: ƒ push(path, state)
replace: ƒ replace(path, state)
location:
pathname: "/about"
search: ""
state: undefined
match:
params: {}
path: "/about"
url: "/about"
路由传参
动态路由传递 params 参数
<!-- 当路由匹配到 /content/:id 时,展示新闻详情页 -->
<Route path="/content/:id" component={NewsContent}/>
// 新闻列表页
import React, { Component } from 'react';
import { Link } from "react-router-dom";
class News extends Component {
state = {
infos:[
{ aid:1, info:"河南" },
{ aid:2, info:"江苏" }
]
}
render() {
return (
<div>
{
this.state.infos.map((value,index)=>{
return <p key={value.aid}><Link to={`/content/${value.aid}`}>{value.info}</Link></p>
})
}
</div>
);
}
}
export default News;
之后在新闻详情页组件,可以通过this.props.match.params.aid获取到参数
传递 get 参数
<!-- 注意此处和上面动态路由有区别,动态路由是 :aid ,而 get 传值不需要 -->
<!-- 正常注册路由 -->
<Route path="/content" component={NewsContent}/>
import React, { Component } from 'react';
import { Link } from "react-router-dom";
class Pnews extends Component {
state = {
infos:[{ aid:1, info:"北京" },
{ aid:2, info:"上海" } ]
}
render() {
return (
<div>
{
this.state.infos.map((value,index)=>{
// 这里直接像 url 一样,在 url 后面以 search 的形式传参
return <p key={index}><Link to={`/pcontent?aid=${value.aid}`}>{value.info}</Link></p>
})
}
</div>
);
}
}
export default Pnews;
之后在新闻详情页组件,可以通过this.props.location.search获取到参数
传递 state 参数
<!-- 正常注册路由 -->
<Route path="/content" component={NewsContent}/>
<!-- 传递参数 -->
<Link to={ { pathname:'/demo/test',state: {name:'tom',age:18} } }>详情</Link>
console.log(this.props.location.state) // 接收参数
编程式路由导航
// 借助 this.prosp.history 对象上的 API 操作路由跳转、前进、后退
this.prosp.history.push(url) // 在路由栈中保留当前路由记录,并跳转到 url 路由
this.prosp.history.replace(url) // 不保留当前路由记录,跳转到 url 路由
this.prosp.history.goBack() // 回退
this.prosp.history.goForward()
this.prosp.history.go() // 前进
路由模块化
/****** APP.jsx ******/
import React, { Component } from 'react';
import './assets/css/App.css';
import Home from './components/Home.jsx';
import New from './components/New.jsx';
import { BrowserRouter as Router, Route,Link } from "react-router-dom";
import Info1 from './components/New/Info1.jsx';
import Info2 from './components/New/Info2.jsx';
// 配置路由,甚至可以把它单独提出一个js的文件
let routes=[
{
path:'/',
component:Home,
exact:true
},
{
path:'/new',
component:New,
routechilden:[
{
path:'/new/',
component:Info1
},
{
path:'/new/info',
component:Info2
}
]
}
]
class App extends Component {
render() {
return (
<Router>
<div>
<Link to='/new'>新闻页面</Link>
{/* 不需要配置嵌套路由的写法
{
routes.map((route,index)=>{
if(route.exact){
return <Route exact key={index} path={route.path} component={route.component}/>
}else{
return <Route key={index} path={route.path} component={route.component}/>
}
})
} */}
{/* 需要配置嵌套路由的写法
以下写法是基本上的固定写法,因为组件传参的方式在路由
中无效,所以下面适用于子路由存在的情况下
但是下面childroutes这个是可以自定义,但是不能是
childerns(可能内部已经使用)
*/}
{
routes.map((route,index)=>{
if(route.exact){
return <Route exact key={index} path={route.path} render={
props=>(
<route.component {...props} childroutes={route.routechilden}/>
)
}/>
}else{
return <Route key={index} path={route.path} render={
props=>(
<route.component {...props} childroutes={route.routechilden}/>
)
}/>
}
})
}
</div>
</Router>
);
}
}
export default App;
版权声明:本文为weixin_43842373原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。