• antd结合reactRouter实现侧边栏菜单动态渲染


    目录

    声明式方式

    编程式方式

    最终版本


    声明式方式

    目录结构是这个样子的

    首先,需要安装react-router-dom和antd这两个插件(路由前面帖子有讲解)

    yarn add react-router-dom antd     或      npm i react-router-dom antd --save

    然后在index.js中做出配置

    1. import React from 'react'
    2. import ReactDOM from 'react-dom/client'
    3. import App from './App'
    4. // 这里路由采用了浏览器模式
    5. import { BrowserRouter as Router } from 'react-router-dom'
    6. // 一定引入antd的样式
    7. import 'antd/dist/antd.css'
    8. const root = ReactDOM.createRoot(document.getElementById('root'))
    9. root.render(
    10. <React.StrictMode>
    11. <Router>
    12. <App />
    13. Router>
    14. React.StrictMode>
    15. )

    在router.js文件中写入路由规则(四级五级路由就再进行嵌套)

    1. import Index from '../pages/Index.jsx'
    2. import Demo from '../pages/Demo.jsx'
    3. import { HeartOutlined } from '@ant-design/icons'
    4. const routes = [
    5. {
    6. path: '/',
    7. element: <Index />,
    8. icon: <HeartOutlined />,
    9. label: '首页',
    10. },
    11. {
    12. path: '/demo',
    13. element: <Demo />,
    14. icon: <HeartOutlined />,
    15. label: '朋友',
    16. },
    17. {
    18. path: '/about',
    19. label: '关于',
    20. icon: <HeartOutlined />,
    21. children: [
    22. {
    23. path: 'music',
    24. element: <Demo />,
    25. label: '音乐',
    26. icon: <HeartOutlined />,
    27. },
    28. {
    29. path: 'movie',
    30. element: <Demo />,
    31. label: '电影',
    32. icon: <HeartOutlined />,
    33. },
    34. ],
    35. },
    36. {
    37. path: '/my',
    38. label: '我的',
    39. icon: <HeartOutlined />,
    40. children: [
    41. {
    42. path: 'money',
    43. label: '钱包',
    44. icon: <HeartOutlined />,
    45. children: [
    46. {
    47. path: 'yue',
    48. element: <Demo />,
    49. label: '余额',
    50. icon: <HeartOutlined />,
    51. },
    52. ],
    53. },
    54. {
    55. path: 'message',
    56. element: <Demo />,
    57. label: '信息',
    58. icon: <HeartOutlined />,
    59. },
    60. ],
    61. },
    62. ]
    63. export default routes

    最后在App.js文件中引入布局组件,实现渲染

    1. import { Layout, Menu } from 'antd'
    2. import React from 'react'
    3. // 引入路由规则文件
    4. import routes from './router/router.js'
    5. import { Link, useRoutes } from 'react-router-dom'
    6. const { Sider, Content, Header } = Layout
    7. export default function App() {
    8. const element = useRoutes(routes)
    9. // Menu组件通过指定items属性,进行菜单渲染
    10. const items = []
    11. // 对路由规则数组进行遍历,并对其进行改造,改造成与Menu的items属性相同的结构
    12. routes.forEach((item) => {
    13. items.push({
    14. label: <Link to={item.path}>{item.label}Link>,
    15. key: item.path,
    16. icon: item.icon,
    17. children:
    18. item.children &&
    19. item.children.map((child) => {
    20. return {
    21. label: <Link to={item.path + '/' + child.path}>{child.label}Link>,
    22. key: item.path + '/' + child.path,
    23. icon: child.icon,
    24. children:
    25. child.children &&
    26. child.children.map((sun) => {
    27. return {
    28. label: (
    29. <Link to={item.path + '/' + child.path + '/' + sun.path}>
    30. {sun.label}
    31. Link>
    32. ),
    33. key: item.path + '/' + child.path + '/' + sun.path,
    34. icon: sun.icon,
    35. }
    36. }),
    37. }
    38. }),
    39. })
    40. })
    41. return (
    42. <>
    43. <Layout>
    44. <Sider theme="dark">
    45. <div
    46. style={{
    47. height: '28px',
    48. margin: '16px',
    49. background: 'rgba(255, 255, 255, 0.2)',
    50. }}
    51. />
    52. <Menu theme="dark" mode="inline" items={items}>Menu>
    53. Sider>
    54. <Layout>
    55. <Header>Header>
    56. <Content>{element}Content>
    57. Layout>
    58. Layout>
    59. )
    60. }

    这是Menu组件的items结构

    最终的效果如下

    编程式方式

    目录结构是这样的

    首先,需要安装react-router-dom和antd这两个插件(路由前面帖子有讲解)

    yarn add react-router-dom antd     或      npm i react-router-dom antd --save

    然后在index.js中做出配置

    1. import React from 'react'
    2. import ReactDOM from 'react-dom/client'
    3. import App from './App'
    4. // 这里路由采用了浏览器模式
    5. import { BrowserRouter as Router } from 'react-router-dom'
    6. // 一定引入antd的样式
    7. import 'antd/dist/antd.css'
    8. const root = ReactDOM.createRoot(document.getElementById('root'))
    9. root.render(
    10. <React.StrictMode>
    11. <Router>
    12. <App />
    13. Router>
    14. React.StrictMode>
    15. )

    在router.js文件中写入路由规则(四级五级路由就再进行嵌套)

    1. import Home from '../pages/Home'
    2. import Movie from '../pages/Movie'
    3. import Music from '../pages/Music'
    4. import Money from '../pages/Money'
    5. import Person from '../pages/Person'
    6. import { SmileOutlined } from '@ant-design/icons'
    7. const routes = [
    8. {
    9. path: '/',
    10. label: '首页',
    11. element: <Home />,
    12. icon: <SmileOutlined />,
    13. },
    14. {
    15. path: '/about',
    16. label: '关于',
    17. icon: <SmileOutlined />,
    18. children: [
    19. {
    20. path: 'music',
    21. label: '音乐',
    22. element: <Music />,
    23. icon: <SmileOutlined />,
    24. },
    25. {
    26. path: 'movie',
    27. label: '电影',
    28. element: <Movie />,
    29. icon: <SmileOutlined />,
    30. },
    31. ],
    32. },
    33. {
    34. path: '/my',
    35. label: '我的',
    36. icon: <SmileOutlined />,
    37. children: [
    38. {
    39. path: 'money',
    40. label: '余额',
    41. element: <Money />,
    42. icon: <SmileOutlined />,
    43. },
    44. {
    45. path: 'message',
    46. label: '信息',
    47. icon: <SmileOutlined />,
    48. children: [
    49. {
    50. path: 'person',
    51. label: '个人信息',
    52. element: <Person />,
    53. icon: <SmileOutlined />,
    54. },
    55. ],
    56. },
    57. ],
    58. },
    59. ]
    60. export default routes

     最后在App.js文件中引入布局组件,实现渲染

    1. import { useState } from 'react'
    2. import { Layout, Menu, Switch } from 'antd'
    3. import { useRoutes, useNavigate } from 'react-router-dom'
    4. import routes from './router/router'
    5. const { Header, Sider, Content } = Layout
    6. function App() {
    7. let element = useRoutes(routes)
    8. const navigate = useNavigate()
    9. const items = []
    10. routes.forEach((item) => {
    11. items.push({
    12. label: item.label,
    13. key: item.path,
    14. icon: item.icon,
    15. children:
    16. item.children &&
    17. item.children.map((child) => {
    18. return {
    19. label: child.label,
    20. key: item.path + '/' + child.path,
    21. icon: child.icon,
    22. children:
    23. child.children &&
    24. child.children.map((sun) => {
    25. return {
    26. label: sun.label,
    27. key: item.path + '/' + child.path + '/' + sun.path,
    28. icon: sun.icon,
    29. // 有四级五级菜单就接着写,最好用递归的方式,但是我不会写
    30. }
    31. }),
    32. }
    33. }),
    34. })
    35. })
    36. const [theme, setTheme] = useState('dark')
    37. const changeTheme = (value) => {
    38. setTheme(value ? 'dark' : 'light')
    39. }
    40. const onClick = (e) => {
    41. navigate(e.key)
    42. }
    43. return (
    44. <div className="App">
    45. <Layout>
    46. <Sider>
    47. <Switch
    48. checked={theme === 'dark'}
    49. onChange={changeTheme}
    50. checkedChildren="Dark"
    51. unCheckedChildren="Light"
    52. />
    53. <Menu theme={theme} onClick={onClick} mode="inline" items={items} />
    54. Sider>
    55. <Layout>
    56. <Header style={{ background: '#ccc' }}>HeaderHeader>
    57. <Content>{element}Content>
    58. Layout>
    59. Layout>
    60. div>
    61. )
    62. }
    63. export default App

    最终效果

    最终版本

    • 包含了懒加载,直接把路由文件改造成Menu组件需要的结构,这样Menu组件只需要引入router.js文件,并把items属性的值为路由规则即可

    router.js

    1. import { lazy, Suspense } from 'react'
    2. import Home from '../pages/Home'
    3. import { SmileOutlined } from '@ant-design/icons'
    4. // 路由懒加载
    5. const Music = lazy(() => import('../pages/Music'))
    6. const Movie = lazy(() => import('../pages/Movie'))
    7. const Money = lazy(() => import('../pages/Money'))
    8. const Person = lazy(() => import('../pages/Person'))
    9. const routes = [
    10. {
    11. path: '/',
    12. key: '/',
    13. label: '首页',
    14. element: <Home />,
    15. icon: <SmileOutlined />,
    16. },
    17. {
    18. path: '/about',
    19. key: '/about',
    20. label: '关于',
    21. icon: <SmileOutlined />,
    22. children: [
    23. {
    24. path: 'music',
    25. key: 'music',
    26. label: '音乐',
    27. element: (
    28. <Suspense fallback={<>}>
    29. <Music />
    30. Suspense>
    31. ),
    32. icon: <SmileOutlined />,
    33. },
    34. {
    35. path: 'movie',
    36. key: 'movie',
    37. label: '电影',
    38. element: (
    39. <Suspense fallback={<>}>
    40. <Movie />
    41. Suspense>
    42. ),
    43. icon: <SmileOutlined />,
    44. },
    45. ],
    46. },
    47. {
    48. path: '/my',
    49. key: '/my',
    50. label: '我的',
    51. icon: <SmileOutlined />,
    52. children: [
    53. {
    54. path: 'money',
    55. key: 'money',
    56. label: '余额',
    57. element: (
    58. <Suspense fallback={<>}>
    59. <Money />
    60. Suspense>
    61. ),
    62. icon: <SmileOutlined />,
    63. },
    64. {
    65. path: 'message',
    66. key: 'message',
    67. label: '信息',
    68. icon: <SmileOutlined />,
    69. children: [
    70. {
    71. path: 'person',
    72. key: 'person',
    73. label: '个人信息',
    74. element: (
    75. <Suspense fallback={<>}>
    76. <Person />
    77. Suspense>
    78. ),
    79. icon: <SmileOutlined />,
    80. },
    81. ],
    82. },
    83. ],
    84. },
    85. ]
    86. export default routes

    App.js

    1. import { Layout, Menu } from 'antd'
    2. import { useRoutes, useNavigate } from 'react-router-dom'
    3. import routes from './router/router'
    4. const { Header, Sider, Content } = Layout
    5. function App() {
    6. let element = useRoutes(routes)
    7. const navigate = useNavigate()
    8. const onClick = (e) => {
    9. let path = e.keyPath.reverse().join('/')
    10. navigate(path)
    11. }
    12. return (
    13. <div className="App">
    14. <Layout>
    15. <Sider>
    16. <Menu theme="dark" onClick={onClick} mode="inline" items={routes} />
    17. Sider>
    18. <Layout>
    19. <Header style={{ background: '#ccc' }}>HeaderHeader>
    20. <Content>{element}Content>
    21. Layout>
    22. Layout>
    23. div>
    24. )
    25. }
    26. export default App

    效果如下

  • 相关阅读:
    3715. 最少交换次数(北京师范大学考研机试题)
    Linux内存管理(十):unflatten_device_tree 详解
    【EC200U】GPS定位
    空心三角形
    java初探之代理模式
    赛前指导:第二届未来飞行器挑战赛实践赛道之技术详解
    猿创征文|网络安全的十大经典工具介绍
    计算机毕业设计 SSM+Vue旅游信息平台系统 景区旅游系统 旅游咨询信息系统 旅游网址管理系统Java Vue MySQL数据库 远程调试 代码讲解
    传统的回调函数与 ES6中的promise回调以及 ES7 的async/await终极的异步同步化
    【Pandas总结】第四节 Pandas 缺失值处理(通过实例进行演示)
  • 原文地址:https://blog.csdn.net/qq_52845451/article/details/127459243