React Router
//-dom代表给浏览器应用使用的
npm install react-router-dom
-
目前版本是 "react-router-dom": "^6.18.0"
使用
新建文件 src/router/MyRouter.tsx
*
TypeScript
import { Navigate, RouteObject, useRoutes } from "react-router-dom";
import { Route } from "../model/Student";
import A8Login from "../pages/A8Login";
import A8Main from "../pages/A8Main";
import A8NotFound from "../pages/A8NotFound";
import { lazy } from "react";
import RoutesStore from "../store/RoutesStore";
import { observer } from "mobx-react-lite";
export function load(name: string) {
//lazy方法可以根据字符串获得字符串组件对应着的组件标签
const Page = lazy(() => import(`../pages/${name}`));
console.log(Page);
return <Page></Page>;
}
function MyRouter() {
console.log(RoutesStore.routes)
const router = useRoutes(RoutesStore.routes);
return router;
}
//注意导入 router 对象时,用 observer 做了包装,这样能够在 store 发生变化时重建 router 对象
export default observer(MyRouter)
index.tsx 修改为
*
TypeScript
import ReactDOM from "react-dom/client";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { ConfigProvider } from "antd";
import zhCN from "antd/es/locale/zh_CN";
import MyRouter from "./router/MyRouter";
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<ConfigProvider locale={zhCN}>
<BrowserRouter>
<MyRouter></MyRouter>
</BrowserRouter>
</ConfigProvider>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
A8Main 的代码
*
TypeScript
import {
DownCircleOutlined,
MenuFoldOutlined,
VerticalAlignTopOutlined,
} from "@ant-design/icons";
import { Button, Layout, Menu } from "antd";
import { ItemType } from "antd/es/menu/hooks/useItems";
import { Link, Navigate, Outlet, useNavigate } from "react-router-dom";
import Icon from "../store/Icon";
import StudentStore from "../store/StudentStore";
import RoutesStore from "../store/RoutesStore";
import { observer } from "mobx-react-lite";
import { useEffect } from "react";
function A8Main() {
const items: ItemType[] = [
{
label: <Link to="/student">学生管理</Link>,
key: 1,
icon: <DownCircleOutlined />,
},
{
label: <Link to="/teacher">教师管理</Link>,
key: 2,
icon: <VerticalAlignTopOutlined />,
},
{
label: "用户管理",
key: 3,
icon: <MenuFoldOutlined />,
children: [
{
label: "功能一",
key: 31,
icon: <Icon name="PicLeftOutlined"></Icon>,
},
{
label: "功能二",
key: 32,
icon: <Icon name="BorderHorizontalOutlined"></Icon>,
},
],
},
];
const nav = useNavigate();
//点击注销按钮,清空localStorage里面和state数据,跳转到登录页面
function onClick() {
RoutesStore.reset();
nav("/login");
}
//useEffect()的执行时机是先生成了jsx代表,然后执行了副作用,然后再渲染,正在渲染的时候执行了跳转,所以看到
//主页一闪而过,
/* useEffect(() => {
if (RoutesStore.username === "") {
nav("/login");
}
}, []); */
if (RoutesStore.username === "") {
return <Navigate to={"/login"}></Navigate>;
}
return (
<Layout>
<Layout.Header>
<span>欢迎您【{RoutesStore.username}】</span>
<Button onClick={onClick}>注销</Button>
</Layout.Header>
<Layout>
<Layout.Sider>
<Menu items={RoutesStore.menus} theme="dark" mode="inline"></Menu>
</Layout.Sider>
<Layout.Content>
<Outlet></Outlet>
</Layout.Content>
</Layout>
</Layout>
);
}
export default observer(A8Main);
-
Navigate 的作用是重定向
-
load 方法的作用是懒加载组件,更重要的是根据字符串找到真正的组件,这是动态路由所需要的
-
children 来进行嵌套路由映射,嵌套路由在跳转后,并不是替换整个页面,而是用新页面替换父页面的 Outlet 部分