路由的安装和引入
-
安装
cnpm i react-router-dom -S
-
引入
-
hash路由:HashRouter
import { HashRouter } from 'react-router-dom'
-
history路由:BrowserRouter
import { HistoryRouter } from 'react-router-dom'
-
-
注意
路由的所有配置项必须在HashRouter或者BrowserRouter包裹范围之内
路由的配置
我们以HashRouter为示例:↓
路由的显示
-
路由的显示需要依赖
Route
组件,所以需要先进行引入import { HashRouter,Route } from 'react-router-dom'
-
配置
Route
组件的配置项Route组件的参数:
path:路由的匹配路径
components:匹配成功后渲染的组件(值为组件名称)
render:路径匹配成功后渲染的组件的render方式 (值为一个函数,返回一个组件或标签)
exact:完全匹配
// 引入所需的组件,用component方式渲染 import Home from './components/home' import Classify from './components/classify' import Order from './components/Order' export default class App extends Component{ render(){ return ( <HashRouter> <Route path="/home" component={Home}></Route> <Route path="/classify" component={Classify}></Route> <Route path="/order" component={Order}></Route> </HashRouter> ) } }
// 或者用render的方式渲染 // ... <HashRouter> <Route path="/home" render={()=><Home/>}></Route> <Route path="/classify" render={()=><Classify/>}></Route> <Route path="/order" render={()=><Order/>}></Route> </HashRouter> // ...
如此一来,路由的最基本的功能就完成了。
重点!!!!!!
component方式和render方式的区别:
-
用component渲染页面的时候,会默认给渲染的组件传递三个值:history、match、location。render需要手动给函数加参数(也可以通过withRouter来搞定):
// 传统写法: <Route path="/home" render={({history,match,location})=>{ return <Home history match location/> }}></Route> // 解构传值: <Route path="/detail" render={(props)=><Home {...props}/>}></Route>
render 可以渲染组件,也可以渲染标签
render 渲染的时候,可以进行传值。因为是标签,可以直接属性传值,props取值
一般情况下,通过render 的形式进行路由嵌套
render 更自由,可以进行更多的业务逻辑
withRouter 高阶组件*
对 render 渲染的路由组件进行加工,使其拥有history、match、location三个参数
引入:
import { withRouter } from 'react-router-dom'
使用:
{{/* 导出时用 withRouter 对创建的组件进行加工,则组件内即可访问history、match和location */}}
export default withRouter(MyComponent);
路由的跳转方式
常规的路由的跳转有以下的几种方式:
-
a标签
a标签实现路由跳转很简单,我们并不需要做太多东西。
<a href="#/home">首页</a> <a href="#/classify">分类</a>
-
Link (没有选中标识的导航)
Link 跳转是嵌入在
react-router-dom
里的,所以需要先进行引入。import { HashRouter,Route,Link } from 'react-route-dom'
然后再进行配置:
// Link组件的跳转路径在 to 属性里 <Link to="/home">首页</Link> <Link to="/classify">分类</Link>
-
NavLink (导航栏跳转——有选中标识的导航)
NanLink 和 Link 的区别不大,依然是先进行引入:
import { HashRouter,Route,NavLink } from 'react-route-dom'
然后进行配置:
// NavLink 组件的跳转路径也在 to 属性里 <NavLink to="/home">首页</NavLink> <NanLink to="/classify">分类</NanLink>
与
Link
组件不同的是,NAVLink
组件在活跃项身上会有一个类名为active
的标识:于是可以在
active
中进行相对应的样式编写。配置项:
- to:需要跳转的路径
- activeClassName:活跃项的类名(默认为
active
) - activeStyle:活跃项的样式
-
编程式导航
如果用
this.props.history.xxx
的方式,必须要有history
参数,用component
方式渲染的页面默认有,如果用render
渲染,需要手动传参。-
this.props.history.push
跳转到
this.props.history.push("/home");
-
this.props.history.goBack
返回
this.props.history.goBack();
this.props.history.goForward
this.props.history.go
this.props.history.replace
-
路由传值
-
动态路由传值(常用)
-
在定义路由的时候通过
/:属性
的方式来定义传递的属性<Route to="/detail/:id" component={Detail}></Route>
-
-
在路由跳转的时候通过
/:值
的方式来传递数据<Link to="/detail/"+item.id>{item.name}</Link>
-
在需要接受数据的页面通过
this.props.match.params
来进行接收<h2>接收到商品id为:{this.props.match.params.id}</h2>
-
query传值
-
在路由跳转的时候通过query传值的方式进行参数的传递
<Link to="/detail?id="+item.id>{item.name}</Link>
-
-
在需要接收数据的页面通过
this.props.location.search
进行接收<h2>接收到商品id为:{url.parse(this.props.location.search).query}</h2>
-
内存传值(自己取的名)
-
在路由跳转的时候通过属性对象的方式进行参数的传递
<Link to={{ path:"/detail", // query的名字是自己取的 query:{ id:item.id } }}>{item.name}</Link>
-
-
jieshou
this.props.location
<h2>接收到商品id为:{this.props.location.query.id}</h2>
因为这种方式把传递的值存在了对象里,所以刷新页面后值会消失,可以用于登录返回页面路径的存储
路由嵌套
路由如果要嵌套的话,父级路由必须要用 render
的方式来渲染,在函数内对子级路由进行操作。
<Route path="/father" render={()=>{
return (
<Fragment>
<Route component={Father}/> {/* 显示父组件 */}
<Route path="/father/childone" component={ChildOne}/>
<Route path="/father/childtwo" component={ChildTwo}/>
</Fragment>
)
}}></Route>
路由重定向——Redirect
路由重定向是由 Redirect
组件来完成的
import { Redirect } from 'react-router-dom'
//...
// 如果在 "/" 路径,重定向到 "/home" 路径
<Redirect from="/" to="/home" />
路由的单一匹配——Switch,完全匹配——exact
首先引入 Switch
组件,然后直接包裹在作用范围内
import { Switch } from 'react-router-dom'
// 用 Switch 组件包裹你想要作用的路由
export default class App extends Component{
render(){
return (
<HashRouter>
<Switch>
{/* exact 表示精准匹配,只有完全满足路径才会做相应操作 */}
<Route path="/home" component={Home} exact/>
<Route path="/classify" component={Classify} />
<Route path="/order" component={Order} />
</Switch>
</HashRouter>
)
}
}
完整的路由嵌套:
{/* 一个完整的路由嵌套 */}
<Route path="/father" render={()=>(
<Fragment>
<Route component={Father}/>
<Switch>
<Redirect from="/father" to="/father/childone" exact />
<Route path="/father/childone" component={ChildOne}/>
<Route path="/father/childtwo" component={ChildTwo}/>
</Switch>
</Fragment>
)}></Route>
路由懒加载——react-loadable
使用路由的懒加载可以提升性能,增加Loading以提高用户体验等
-
安装
cnpm i react-loadable -S
-
引入
import loadable from 'react-loadable'
-
配置
不用路由懒加载的时候,组件是默认的引入方式:
import Home from './components/home'
用路由懒加载引入组件:
const Home = loadable({ loader:()=>import("./components/home"), loading:Loading {/* Loading是自己的Loading组件 */} })