一、安装路由
npm install react-router-dom
App.tsx 文件
import React from 'react';
import {Switch, BrowserRouter} from 'react-router-dom';
// import moduleName from 'module';
import PagesLayout from './layout';
import { ConfigProvider } from 'antd';
import 'moment/locale/zh-cn';
import moment from 'moment';
import './App.less'
moment.locale('zh-cn')
class App extends React.Component {
render() {
return (
<div className="App" id="rootWebApp">
<ConfigProvider>
<BrowserRouter >
<Switch>
<PagesLayout />
</Switch>
</BrowserRouter>
</ConfigProvider>
</div>
);
}
}
export default App;
index.tsx 文件
import React from 'react';
import { Redirect, withRouter, RouteComponentProps } from 'react-router-dom';
import { getAuthority } from '../utils/authority';
import { routes, lazyLoadRoute } from './routerMap';
import { homePage } from '../utils/base';
class Router extends React.Component<RouteComponentProps> {
render() {
const { location } = this.props;
const { pathname } = location
// 获取token
const isLogin = getAuthority();
// 获取路由对应的组件
const targetRouterConfig = routes?.find(
(item) => item.path === pathname
);
const routelist = lazyLoadRoute(routes)
// 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆
if (!isLogin && targetRouterConfig?.auth) {
return <Redirect to='/login' />
};
// 如果是登陆状态,想要跳转到登陆,重定向到主页
if (pathname === '/login' && isLogin) {
return <Redirect to={homePage} />
};
// 根目录重定向到首页
if (pathname === '/') {
return <Redirect to={homePage} />
};
// 路由不合法跳转404
if (!targetRouterConfig) {
return <Redirect to='/404' />
};
// 如果路由合法,就跳转到相应的路由
return (
<React.Suspense fallback={<>正在加载……</>}>
{routelist}
</React.Suspense>
);
};
};
export default withRouter(Router)
在 routerMap.tsx 文件中我们使用的是组件的懒加载React.lazy,根据 React 的介绍,使用懒加载需要使用 Suspense 组件过度
fallback 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense 组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense 组件包裹多个懒加载组件。
routerMap.tsx 文件
import React from 'react';
import { Route } from 'react-router-dom';
const Exception = React.lazy(() => import(`../pages/Exception`))
const Home = React.lazy(() => import(`../pages/home`))
const Login = React.lazy(() => import(`../pages/login`))
/**
* 路由配置
* authority:权限控制,可以为一组权限数组,也可以为字符串,为字符串时多个权限用逗号隔开,
* component:页面组件路径,
* path:路由路径
*/
export interface IRouter {
authority?: string[] | string; // 权限控制,设置进入此页面的所需要权限,设置后将覆盖默认权限。
component: any; // 加载的组件
auth?: boolean; // 是否需要判断登录
path: string; // 对应的地址
name?: string; // 路由名称
children?: IRouter[];
}
// 路由目录
export const routes: IRouter[] = [
{ path: "/home", name: "Home", component: Home, auth: true },
{ path: "/login", name: "Login", component: Login },
{ path: "/404", name: "404", component: Exception },
]
// 加载路由组件
export const lazyLoadRoute = (routes: IRouter[]) => {
return routes?.map((route: IRouter) => {
return (
<Route path={route.path} component={route.component} />
)
})
}
-
BrowserRouter
包裹Link
和Route
的组件,使得UI组件与地址URL保持同步,若Link
和Route
不被BrowserRouter
包裹,则会报错。另外,Link
编写的好的路径,在注册时,Link和Route
必须要在同一个BrowserRouter
内才会起作用,不能分开在不同的BrowserRouter
。通常可以像上面的例子一样,直接在index.js中包含<App/>
组件使用。 -
Route
使用该组件可以对上面Link编写好的路由路径进行注册,并设置路径对应要展示的组件。注册的路由在进行匹配时,是从上到下按顺序匹配的,若没有Switch
包裹,无论有多少个Route
都进行一遍扫描匹配。
文档原话:它最基本的职责是在location
与Route
的path
匹配时呈现一些 UI。- 常用属性:
exact
:如果为true
,则只有在路径完全匹配时才匹配。默认模糊匹配,即浏览器地址只有前面部分完美匹配时才显示,如浏览器为 /about/a/b/c,而Route
为 /about,可以匹配成功,两者反之则不行。
path
:任何可以解析的有效的 URL 路径,一般对应Link
的to
属性
component
:只有当位置匹配时才会渲染的 React 组件。
render
:与component作用相同,该方式使用内联编写,而不引用外部暴露的 React 组件。render
的类型是function
,Route会渲染这个function
的返回值。因此它的作用就是附加一些额外的逻辑
sensitive
:如果路径区分大小写,则为true
,则匹配。
- 常用属性:
-
Switch
Route默认是全部扫描的,就算路由路径是第一个而且已经成功匹配,还是要向下继续扫描,使用Switch
包裹Route
,使得一旦路径匹配就不继续向下匹配了,也就是说,一个路径只匹配一次 -
Redirect
重定向,当路由没有匹配的时候,给一个指定的路径去匹配,to
属性指定一个路径 -
withRouter
可以通过withRouter
高阶组件访问history
对象的属性和最近的的match
。 当路由渲染时,withRouter
会将已经更新的match
,location
和history
属性传递给被包裹的组件。
将一般组件变成路由组件,即组件props
能接收到history
,location
,match
三个参数
路由配置请参考:
react 项目模板搭建(1)—— 加入 less 、 sass
react 项目模板搭建(3)—— 加入 react-redux 状态管理
参考:
react-router-dom入门基本使用
react-router-dom简介
react-router-dom5.0的路由拦截(路由守卫)实现