React Router
//-dom代表给浏览器应用使用的
npm install react-router-dom
-
目前版本是 "react-router-dom": "^6.18.0"
-
使用
新建文件 src/router/MyRouter.tsx
-
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 修改为
-
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 的代码
-
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 部分