在React v18中使用React Router v6和Ant Design (antd) v5来动态生成菜单和路由,同时使用MockJS来模拟接口请求菜单数据,可以按照以下步骤进行:
-
创建一个React应用: 使用Create React App或您喜欢的其他方式创建一个React应用。
-
安装必要的依赖: 在项目目录中运行以下命令来安装React Router v6、Ant Design v5和MockJS:
kotlinnpm install react-router-dom@6 antd@5 mockjs
-
设置MockJS模拟接口数据: 在项目中创建一个名为
mock
的文件夹,并在其中创建一个用于模拟接口数据的文件,例如menuMock.js
:javascript// mock/menuMock.js import Mock from 'mockjs'; const menuData = Mock.mock({ 'menuList|5-10': [ { 'id|+1': 1, 'name': '@word', 'path': '@word', }, ], }); export default menuData.menuList;
在应用的入口文件中,如
src/index.js
,导入MockJS并使用上面创建的模拟数据:javascript// src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import menuMock from './mock/menuMock'; // 导入模拟数据 import Mock from 'mockjs'; Mock.mock('/api/menu', 'get', () => { return menuMock; }); ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
-
创建菜单组件和路由: 在项目中创建一个用于渲染菜单和路由的组件,例如
MenuRouter.js
:javascript// src/MenuRouter.js import React, { useState, useEffect } from 'react'; import { Link, Route, Routes } from 'react-router-dom'; import { Menu, Layout } from 'antd'; const { Sider } = Layout; function MenuRouter() { const [menuData, setMenuData] = useState([]); useEffect(() => { fetch('/api/menu') .then((response) => response.json()) .then((data) => setMenuData(data)) .catch((error) => console.error('Error fetching menu data:', error)); }, []); return ( <Sider width={200} theme="light"> <Menu mode="vertical"> {menuData.map((item) => ( <Menu.Item key={item.path}> <Link to={item.path}>{item.name}</Link> </Menu.Item> ))} </Menu> <Routes> {menuData.map((item) => ( <Route key={item.path} path={item.path} element={<div>{item.name} Content</div>} /> ))} </Routes> </Sider> ); } export default MenuRouter;
-
创建主应用组件: 在项目中创建一个主应用组件,例如
App.js
:javascript// src/App.js import React from 'react'; import { Layout } from 'antd'; import MenuRouter from './MenuRouter'; const { Content } = Layout; function App() { return ( <Layout style={{ minHeight: '100vh' }}> <MenuRouter /> <Layout> <Content style={{ padding: '16px' }}> <h1>Welcome to Your App</h1> </Content> </Layout> </Layout> ); } export default App;
-
启动应用: 最后,在项目根目录中运行应用:
sqlnpm start
应用将启动并在浏览器中打开,您应该能够看到动态生成的菜单和路由,并且MockJS会模拟接口请求菜单数据。请根据您的需求进一步定制和优化这个基础示例。
react-antd-admin 菜单组件,大家可以详细看这个地址
今天我们就来解析下里面的代码
这段代码是一个React组件,用于生成动态的菜单。让我逐步解析它:
-
引入React相关依赖:
import React, { useState, memo } from "react";
: 导入了React核心库,以及useState
和memo
两个React Hook。useState
用于在函数组件中管理状态,memo
用于优化组件性能。
-
引入Ant Design和其他相关依赖:
import { Menu } from 'antd';
: 导入了Ant Design的Menu
组件。import type { MenuProps } from "antd";
: 导入了Menu
组件的类型定义,以便进行类型检查。import { ItemType } from "antd/es/menu/hooks/useItems";
: 导入了ItemType
,这是Ant Design Menu组件中的一个类型。
-
引入其他自定义组件和工具:
import IconFont from "../icon";
: 导入了一个自定义的IconFont
组件。import { NavLink as Link, useLocation } from 'react-router-dom';
: 导入了React Router的相关组件,包括NavLink
和useLocation
。
-
定义了一些类型和接口:
-
type MenuItem = Required<MenuProps>['items'][number];
: 定义了一个MenuItem
类型,它是MenuProps
类型中items
数组的元素类型。 -
interface IMenuItem { ... }
: 定义了一个IMenuItem
接口,用于描述菜单项的结构,包括key
、icon
、children
、label
和type
等属性。
-
-
创建了一个空的
routeMap
对象,用于将路径映射到对应的名称。 -
定义了一个函数
getMenuList(menuList: any[])
用于生成菜单数据。这个函数接收一个菜单数据的数组作为参数,然后递归地将静态菜单数据和传入的菜单数据合并成一个新的菜单数据数组,同时生成openKeys
用于展开子菜单,以及将路径映射到名称的routeMap
。最后,返回openKeys
和tempMenuList
。 -
创建了一个名为
DynamicMenu
的函数组件,它接受一个名为menuData
的参数。- 使用
useLocation
获取当前页面的路径,并设置默认的tempPath
状态。 - 调用
getMenuList
函数生成菜单数据,得到openKeys
和tempMenuList
。 - 定义了一个
onClick
函数,用于处理菜单项的点击事件。 - 返回一个
Menu
组件,使用tempPath
和openKeys
设置默认选中的菜单项和展开的子菜单项,并传入生成的菜单数据tempMenuList
。
- 使用
-
最后,使用
memo
函数包装了DynamicMenu
组件,以优化性能。memo
可以阻止组件在没有改变的 props 的情况下重新渲染。
这个组件的主要作用是根据传入的菜单数据生成一个动态的侧边栏菜单,并根据路由进行高亮显示。它还会将路径映射到对应的名称,以供面包屑导航等功能使用。