a) 安装路由库 5 版本的
//下载router
npm i react-router-dom@5
//下载去除 路径报错的插件
npm i --save-dev @types/react-router-dom
开启配置 允许导入:tsx:因为项目是基于TS的
b) 相关组件
路由管理组件
BrowserRouter 使用 HTML5 历史记录 API(pushState,replaceState 和 popstate 事件)的<Router>来保持您的 UI 与 URL 同步。
HashRouter 使用 URL 的哈希部分(即 window.location.hash)的<Router>来保持您的 UI 与 URL 同步
index.tsx 中:
使用路由组件 :需要使用什么路由自带组件就从 react-router-dom中导入
路由组件的切换,存在挂载和卸载:所以要优化
导入组件
<Router path=" " component={ } />
<Redirect /> 组件用于重定向,但是不生效,需要配合switch组件
<Switch> </Switch> 组件包裹路由规则,
<Router path="*" component={ NotFound } /> 其他路由要加 exact ,不加就默认以什么什么开始都可以匹配,不进404页面:但是:exact 精确匹配:有二级路由的时候取消
重定向
404页面 <Router path="*" component={ NotFound } />
exact 精确匹配:有嵌套路由的取消
c) 声明式导航
<Link to=" "></Link> 渲染成a标签
<NavLink to=" "></NavLink> 渲染成a标签会在自身的路由地址和浏览器的路由地址匹配成功时,自动添加active类
二级路由跳转
使用的组件需要导入
匹配成功的路由。匹配到哪里就在哪个页面渲染。switch提前占位,后边会被组件替换,路由规则本身就是个动态组件
d) 编程式导航:::方便
this.props.history 负责跳路由
this.props.location 负责存储路由信息(地址,参数)
this.props.match 负责存储路由信息(地址,参数)
props.history.push() //跳转路由
props.history.replace()
props.history.go() //前进 or 后退
props.history.goBack() //后退
props.history.goForward() //前进
父中子组件没有路由,但是想跳路由,那就要导入路由,传参,ts一定传好(3个)
解决 TS 报错:
以下包含编程式导航的跳转
比如组件中使用了
事件对象通过button 触发
3. 路由参数
封装路由:::
javascript">// router下routerConfig.ts
//路由表
//配置整个项目的路由
import { lazy } from 'react'
var Index = lazy(()=>import('../views/Index/index.tsx'))
var Login = lazy(()=>import('../views/Login/index.tsx'))
var Detail = lazy(()=>import('../views/Detail/index.tsx'))
var NotFound = lazy(()=>import('../views/NotFound/index.tsx'))
var Home = lazy(()=>import('../views/Index/Home'))
var Cate = lazy(()=>import('../views/Index/Cate'))
var Gwc = lazy(()=>import('../views/Index/Gwc'))
var Mine = lazy(()=>import('../views/Index/Mine'))
export default [
{
path:'/index',
component:Index,
children:[
{
path:'/index/home',
component:Home,
},
{
path:'/index/cate',
component:Cate,
},
{
path:'/index/gwc',
component:Gwc,
},
{
path:'/index/mine',
component:Mine,
},
{
from:'/index',
to:'/index/home',
},
{
path:'*',
component:NotFound,
}
]
},
{
path:'/login',
component:Login,
},
{
path:'/detail',
component:Detail,
},
{
from:'/',
to:'/index',
},
{
path:'*',
component:NotFound,
},
]
javascript">// routerView.tsx
import React, { Component,Suspense } from 'react';
import {Route,Redirect,Switch} from 'react-router-dom'
//根据路由配置表 动态渲染路由规则( Route,Redirect )
//RouterView组件 根据外部传入的路由配置表, 动态渲染路由规则( Route,Redirect )
interface RouteItem {
path?:string,
component?:any,
children?:Array<RouteItem>,
from?:string,
to?:string
}
interface Props {
routes: Array<RouteItem>
}
class RouterView extends Component<Props> {
render() {
return (
<Suspense fallback={<div className='loading'>loading....</div>}>
<Switch>
{
this.props.routes.map((item,index)=>{
//如果有from属性 渲染重定向路由
if( item.from ){
return <Redirect exact from={item.from} to={item.to||''} />
}
//如果有children属性 用render渲染路由( 对应的组件会通过routes属性传入其内部需要用到的嵌套路由配置表 )
else if( item.children ){
return (
<Route path={item.path} render={()=>{
return <item.component routes={item.children} />
}} />
)
}else{ //其他情况 用component渲染路由
return (
<Route path={item.path} component={item.component} />
)
}
})
}
</Switch>
</Suspense>
);
}
}
export default RouterView;
使用