目录
声明式方式
目录结构是这个样子的
首先,需要安装react-router-dom和antd这两个插件(路由前面帖子有讲解)
yarn add react-router-dom antd 或 npm i react-router-dom antd --save
然后在index.js中做出配置
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// 这里路由采用了浏览器模式
import { BrowserRouter as Router } from 'react-router-dom'
// 一定引入antd的样式
import 'antd/dist/antd.css'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>
)
在router.js文件中写入路由规则(四级五级路由就再进行嵌套)
import Index from '../pages/Index.jsx'
import Demo from '../pages/Demo.jsx'
import { HeartOutlined } from '@ant-design/icons'
const routes = [
{
path: '/',
element: <Index />,
icon: <HeartOutlined />,
label: '首页',
},
{
path: '/demo',
element: <Demo />,
icon: <HeartOutlined />,
label: '朋友',
},
{
path: '/about',
label: '关于',
icon: <HeartOutlined />,
children: [
{
path: 'music',
element: <Demo />,
label: '音乐',
icon: <HeartOutlined />,
},
{
path: 'movie',
element: <Demo />,
label: '电影',
icon: <HeartOutlined />,
},
],
},
{
path: '/my',
label: '我的',
icon: <HeartOutlined />,
children: [
{
path: 'money',
label: '钱包',
icon: <HeartOutlined />,
children: [
{
path: 'yue',
element: <Demo />,
label: '余额',
icon: <HeartOutlined />,
},
],
},
{
path: 'message',
element: <Demo />,
label: '信息',
icon: <HeartOutlined />,
},
],
},
]
export default routes
最后在App.js文件中引入布局组件,实现渲染
import { Layout, Menu } from 'antd'
import React from 'react'
// 引入路由规则文件
import routes from './router/router.js'
import { Link, useRoutes } from 'react-router-dom'
const { Sider, Content, Header } = Layout
export default function App() {
const element = useRoutes(routes)
// Menu组件通过指定items属性,进行菜单渲染
const items = []
// 对路由规则数组进行遍历,并对其进行改造,改造成与Menu的items属性相同的结构
routes.forEach((item) => {
items.push({
label: <Link to={item.path}>{item.label}</Link>,
key: item.path,
icon: item.icon,
children:
item.children &&
item.children.map((child) => {
return {
label: <Link to={item.path + '/' + child.path}>{child.label}</Link>,
key: item.path + '/' + child.path,
icon: child.icon,
children:
child.children &&
child.children.map((sun) => {
return {
label: (
<Link to={item.path + '/' + child.path + '/' + sun.path}>
{sun.label}
</Link>
),
key: item.path + '/' + child.path + '/' + sun.path,
icon: sun.icon,
}
}),
}
}),
})
})
return (
<>
<Layout>
<Sider theme="dark">
<div
style={
{
height: '28px',
margin: '16px',
background: 'rgba(255, 255, 255, 0.2)',
}}
/>
<Menu theme="dark" mode="inline" items={items}></Menu>
</Sider>
<Layout>
<Header></Header>
<Content>{element}</Content>
</Layout>
</Layout>
</>
)
}
这是Menu组件的items结构
最终的效果如下
编程式方式
目录结构是这样的
首先,需要安装react-router-dom和antd这两个插件(路由前面帖子有讲解)
yarn add react-router-dom antd 或 npm i react-router-dom antd --save
然后在index.js中做出配置
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// 这里路由采用了浏览器模式
import { BrowserRouter as Router } from 'react-router-dom'
// 一定引入antd的样式
import 'antd/dist/antd.css'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>
)
在router.js文件中写入路由规则(四级五级路由就再进行嵌套)
import Home from '../pages/Home'
import Movie from '../pages/Movie'
import Music from '../pages/Music'
import Money from '../pages/Money'
import Person from '../pages/Person'
import { SmileOutlined } from '@ant-design/icons'
const routes = [
{
path: '/',
label: '首页',
element: <Home />,
icon: <SmileOutlined />,
},
{
path: '/about',
label: '关于',
icon: <SmileOutlined />,
children: [
{
path: 'music',
label: '音乐',
element: <Music />,
icon: <SmileOutlined />,
},
{
path: 'movie',
label: '电影',
element: <Movie />,
icon: <SmileOutlined />,
},
],
},
{
path: '/my',
label: '我的',
icon: <SmileOutlined />,
children: [
{
path: 'money',
label: '余额',
element: <Money />,
icon: <SmileOutlined />,
},
{
path: 'message',
label: '信息',
icon: <SmileOutlined />,
children: [
{
path: 'person',
label: '个人信息',
element: <Person />,
icon: <SmileOutlined />,
},
],
},
],
},
]
export default routes
最后在App.js文件中引入布局组件,实现渲染
import { useState } from 'react'
import { Layout, Menu, Switch } from 'antd'
import { useRoutes, useNavigate } from 'react-router-dom'
import routes from './router/router'
const { Header, Sider, Content } = Layout
function App() {
let element = useRoutes(routes)
const navigate = useNavigate()
const items = []
routes.forEach((item) => {
items.push({
label: item.label,
key: item.path,
icon: item.icon,
children:
item.children &&
item.children.map((child) => {
return {
label: child.label,
key: item.path + '/' + child.path,
icon: child.icon,
children:
child.children &&
child.children.map((sun) => {
return {
label: sun.label,
key: item.path + '/' + child.path + '/' + sun.path,
icon: sun.icon,
// 有四级五级菜单就接着写,最好用递归的方式,但是我不会写
}
}),
}
}),
})
})
const [theme, setTheme] = useState('dark')
const changeTheme = (value) => {
setTheme(value ? 'dark' : 'light')
}
const onClick = (e) => {
navigate(e.key)
}
return (
<div className="App">
<Layout>
<Sider>
<Switch
checked={theme === 'dark'}
onChange={changeTheme}
checkedChildren="Dark"
unCheckedChildren="Light"
/>
<Menu theme={theme} onClick={onClick} mode="inline" items={items} />
</Sider>
<Layout>
<Header style={
{ background: '#ccc' }}>Header</Header>
<Content>{element}</Content>
</Layout>
</Layout>
</div>
)
}
export default App
最终效果
最终版本
- 包含了懒加载,直接把路由文件改造成Menu组件需要的结构,这样Menu组件只需要引入router.js文件,并把items属性的值为路由规则即可
router.js
import { lazy, Suspense } from 'react'
import Home from '../pages/Home'
import { SmileOutlined } from '@ant-design/icons'
// 路由懒加载
const Music = lazy(() => import('../pages/Music'))
const Movie = lazy(() => import('../pages/Movie'))
const Money = lazy(() => import('../pages/Money'))
const Person = lazy(() => import('../pages/Person'))
const routes = [
{
path: '/',
key: '/',
label: '首页',
element: <Home />,
icon: <SmileOutlined />,
},
{
path: '/about',
key: '/about',
label: '关于',
icon: <SmileOutlined />,
children: [
{
path: 'music',
key: 'music',
label: '音乐',
element: (
<Suspense fallback={<></>}>
<Music />
</Suspense>
),
icon: <SmileOutlined />,
},
{
path: 'movie',
key: 'movie',
label: '电影',
element: (
<Suspense fallback={<></>}>
<Movie />
</Suspense>
),
icon: <SmileOutlined />,
},
],
},
{
path: '/my',
key: '/my',
label: '我的',
icon: <SmileOutlined />,
children: [
{
path: 'money',
key: 'money',
label: '余额',
element: (
<Suspense fallback={<></>}>
<Money />
</Suspense>
),
icon: <SmileOutlined />,
},
{
path: 'message',
key: 'message',
label: '信息',
icon: <SmileOutlined />,
children: [
{
path: 'person',
key: 'person',
label: '个人信息',
element: (
<Suspense fallback={<></>}>
<Person />
</Suspense>
),
icon: <SmileOutlined />,
},
],
},
],
},
]
export default routes
App.js
import { Layout, Menu } from 'antd'
import { useRoutes, useNavigate } from 'react-router-dom'
import routes from './router/router'
const { Header, Sider, Content } = Layout
function App() {
let element = useRoutes(routes)
const navigate = useNavigate()
const onClick = (e) => {
let path = e.keyPath.reverse().join('/')
navigate(path)
}
return (
<div className="App">
<Layout>
<Sider>
<Menu theme="dark" onClick={onClick} mode="inline" items={routes} />
</Sider>
<Layout>
<Header style={
{ background: '#ccc' }}>Header</Header>
<Content>{element}</Content>
</Layout>
</Layout>
</div>
)
}
export default App
效果如下
原文链接:https://blog.csdn.net/qq_52845451/article/details/127459243
此处评论已关闭