带有 Material ui 和 Reactjs 的嵌套侧边栏菜单

2023-12-13

我正在尝试使用 Material ui 开发一个侧边栏菜单。我可以制作简单的列表。在我的项目中,我需要嵌套侧边栏菜单,但我无法实现。如果我尝试使用递归函数,它仅提供主标题菜单,而不呈现子元素。请帮我开发它。

嵌套侧边栏菜单的代码如下,

import React, {useState} from 'react';
import { makeStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Collapse from '@material-ui/core/Collapse';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';

const useStyles = makeStyles((theme) => ({
  root: {
    width: '100%',
    maxWidth: 360,
    backgroundColor: theme.palette.background.paper,
  },
  nested: {
    paddingLeft: theme.spacing(4),
  },
}));

export const Menu = ({items}) => {
  const classes = useStyles();
  const [open, setOpen] = useState(true);

  const handleClick = () => {
    setOpen(!open);
  };

  return (
    items.map(item =>
      !item.children ? (
          <div key={item.title}>
            <ListItem button>
              <ListItemIcon>
                {item.icon}
              </ListItemIcon>
              <ListItemText primary={item.title} />
            </ListItem>
          </div>
        ) : (
          <div
            component="nav"
            key={item.title}
          >
            <ListItem button onClick={handleClick}>
              <ListItemIcon>
                {item.icon}
              </ListItemIcon>
              <ListItemText primary={item.title} />
              {open ? <ExpandLess /> : <ExpandMore />}
            </ListItem>
            <Collapse in={open} timeout="auto" unmountOnExit>
              <List component="div" disablePadding>
                <ListItem button className={classes.nested}>
                  <ListItemIcon>
                    {item.icon}
                  </ListItemIcon>
                  <ListItemText>
                    <Menu items={item} />
                  </ListItemText>
                </ListItem>
              </List>
            </Collapse>
          </div>
        )
    )
  );
}

菜单项代码在这里,

import HomeOutlinedIcon from "@material-ui/icons/HomeOutlined";
import LocalLibraryOutlinedIcon from "@material-ui/icons/LocalLibraryOutlined";
import TrendingUpOutlinedIcon from "@material-ui/icons/TrendingUpOutlined";
import DescriptionOutlinedIcon from "@material-ui/icons/DescriptionOutlined";
import React from "react";


export const menu = [
  {
    icon: <HomeOutlinedIcon/>,
    title: 'Home',
    items: []
  },
  {
    icon: <LocalLibraryOutlinedIcon/>,
    title: 'Education',
    items: [
      {
        title:'Technical Analysis',
        items: [
          {
            title: 'The Dow Theory',
            to: '/thedowtheory'
          },
          {
            title: 'Charts & Chart Patterns',
            to: '/chart'
          },
          {
            title: 'Trend & Trend Lines',
            to: '/trendlines'
          },
          {
            title: 'Support & Resistance',
            to: '/sandr'
          },
        ]
      },
      {
        title:'Fundamental Analysis',
        items: [
          {
            title: 'The Dow Theory',
            to: '/thedowtheory'
          },
          {
            title: 'Charts & Chart Patterns',
            to: '/chart'
          },
          {
            title: 'Trend & Trend Lines',
            to: '/trendlines'
          },
          {
            title: 'Support & Resistance',
            to: '/sandr'
          },
        ]
      },
      {
        title:'Elliot Wave Analysis',
        items: [
          {
            title: 'The Dow Theory',
            to: '/thedowtheory'
          },
          {
            title: 'Charts & Chart Patterns',
            to: '/chart'
          },
          {
            title: 'Trend & Trend Lines',
            to: '/trendlines'
          },
          {
            title: 'Support & Resistance',
            to: '/sandr'
          },
        ]
      },
      ]
  },
  {
    icon: <TrendingUpOutlinedIcon/>,
    title: 'Options'
  },
  {
    icon: <DescriptionOutlinedIcon/>,
    title: 'Blog'
  },
]

首先,你有一个错字。你正在循环播放children键而不是items。但即使你解决了这个问题,你的代码仍然不会按照你想要的方式工作。


我会通过创建一个来简化我的方法SingleLevel and MultiLevel可重用组件来处理当前菜单项。如果当前项目有children/items那么我会用MultiLevel其他组件SingleLevel.

单层组件

const SingleLevel = ({ item }) => {
  return (
    <ListItem button>
      <ListItemIcon>{item.icon}</ListItemIcon>
      <ListItemText primary={item.title} />
    </ListItem>
  );
};

多级组件

const MultiLevel = ({ item }) => {
  const { items: children } = item;
  const [open, setOpen] = useState(false);

  const handleClick = () => {
    setOpen((prev) => !prev);
  };

  return (
    <React.Fragment>
      <ListItem button onClick={handleClick}>
        <ListItemIcon>{item.icon}</ListItemIcon>
        <ListItemText primary={item.title} />
        {open ? <ExpandLessIcon /> : <ExpandMoreIcon />}
      </ListItem>
      <Collapse in={open} timeout="auto" unmountOnExit>
        <List component="div" disablePadding>
          {children.map((child, key) => (
            <MenuItem key={key} item={child} />
          ))}
        </List>
      </Collapse>
    </React.Fragment>
  );
};

为了确定要使用哪个组件,我将创建一个hasChildren返回的辅助函数true如果当前项目满足我定义的所有条件,则被视为父菜单项。

utils.js

export function hasChildren(item) {
  const { items: children } = item;

  if (children === undefined) {
    return false;
  }

  if (children.constructor !== Array) {
    return false;
  }

  if (children.length === 0) {
    return false;
  }

  return true;
}

然后我会将所有这些抽象到另一个MenuItem成分。

菜单项组件

const MenuItem = ({ item }) => {
  const Component = hasChildren(item) ? MultiLevel : SingleLevel;
  return <Component item={item} />;
};

最后,这就是我将如何循环menu items

export default function App() {
  return menu.map((item, key) => <MenuItem key={key} item={item} />);
}

Edit lucid-lichterman-s5uhm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有 Material ui 和 Reactjs 的嵌套侧边栏菜单 的相关文章

随机推荐

  • 通过 Angular.js 维护会话

    我正在使用 AngularJS 框架开展一个项目 我对使用这个框架还很陌生 过去我只使用纯 JavaScript 和 jQuery 该项目是一种针对利基市场的网页设计师应用程序 当用户在设计时在页面之间移动时 我想维护他们所做的所有更改的会
  • Babel 在运行 Jest 时不会编译 .test.js 文件

    运行yarn run jest no cache时 抛出一个错误 内容如下 SyntaxError Unexpected token import 我最好的猜测是 babel 没有达到这个测试文件 我需要将它们包含在 babelrc 中吗
  • 数据库:SUBSTRING 直到字符第一次出现

    我有字符串类型 abc 01 abcd 01 或 02 现在我想要子字符串 即 abc abcd 等 我正在使用 db2 as400 请建议通过 RIGHT 或 LEFT 函数进行处理 使用 POSITION 内置函数 格式为 POSITI
  • method_missing 覆盖不起作用

    我编写了一个方便的 ActiveRecord 扩展来将方法委托给基础对象 基于多表继承 class ActiveRecord Base def self acts as base class eval Q def method missin
  • 使用seaborn.swarmplot 将数据点映射到颜色图

    我想生成一个seaborn swarmplot 其中单个数据点的颜色映射到颜色图 我有一个与此类似的数据框 In 48 df Out 48 a c Key 0 1 12 1st 1 4 35 2nd 2 5 12 2nd 3 6 46 1s
  • Angular 2 ng 模块导入

    当我们在顶部导入文件时 导入 ngmodule 装饰器的元数据有什么意义 两个输入之间的差异 这些导入是完全不同的概念 文件顶部的导入是 TypeScript 导入 以使当前文件已知的类 接口和变量 与 Angular2 无关 The Ng
  • Android中使用WallpaperManager设置壁纸

    以下是我的代码 我想使用壁纸管理器设置为壁纸 我在用着通用图像加载器 但我不知道如何实现壁纸管理器 我的 setWall 不起作用 有点令人困惑 import android graphics Bitmap import android o
  • 智能编译器是否可以在不成为语言一部分的情况下完成 std​​::move 所做的所有事情?

    这是一个有点理论上的问题 但是尽管我对 std move 有一些基本的了解 但我仍然不确定它是否为该语言提供了一些理论上无法通过超级智能编译器实现的附加功能 我知道这样的代码 std string s1 STL std string s2
  • Google 表格 - 将某个范围内的值重复“n”次

    I am trying to execute the following in google sheets by repeating certain cell values from a range of cells number of r
  • 无需连接即可获取 WiFi 的 SSID?

    我想连接到SSID应用程序中的 wifi 网络 Code WifiConfiguration conf new WifiConfiguration conf SSID networkSSID 但问题是我不知道network SSID 如何获
  • Flow 无法识别回调内的细化

    此代码通过了流程检查 flow function test list Array
  • 带有相应归属链接的随机背景图片?

    我有一个页面显示 5 张图像数组中的随机背景图像 我还想在页面底部提供该图像的适当归属链接 但我不确定如何使用 javascript 或 php 执行此操作 这就是我现在所拥有的
  • 隐式复制构造函数/赋值运算符的行为

    我有一个关于 C 标准的问题 假设您有一个带有用户定义的复制构造函数和赋值运算符的基类 派生类使用编译器生成的隐式类 派生类的复制 赋值是否调用用户定义的复制构造函数 赋值运算符 或者您是否需要实现调用基类的用户定义版本 感谢您的帮助 如果
  • R 基于应用于多列的多个部分字符串过滤行

    数据集样本 diag01 lt as factor c S7211 J47 J47 K729 M2445 Z509 Z488 R13 L893 N318 L0311 S510 A047 D649 diag02 lt as factor c
  • 序列化对象时忽略继承的类

    当我从一个类继承并序列化新类时 我获得了所有属性 我怎样才能防止这种情况发生 我无法控制我继承的类 所以我无法向其属性添加属性 XmlIgnore Example class A public string PropertyA get se
  • 用单个字符初始化字符串

    我想初始化一个std string具有单个字符 以下代码不起作用 int main string s c cout lt
  • 如何在asp.net core 3中设置json序列化器设置?

    旧版 ASP NET Core 应用程序的 json 序列化器设置是通过添加AddMvc AddJsonOptions 但我不使用AddMvc in asp net core 3 那么如何设置全局 json 序列化设置呢 AddMvc返回一
  • java中会话超时删除cookie

    我正在开发一个java web应用程序 我已经在其中配置了session timeout等于 4 分钟 此应用程序也使用 cookie 我的问题是 4 分钟不活动后 HttpSession 过期 但 cookie 仍保留在浏览器中 年龄设置
  • VBA:文本框新/下一行

    我的文本框需要一些帮助 我的文本框内容由单元格值提供 现在单元格值的构造如下 日期注释 并且它逐渐发生 我可以有多个这样的条目 基本上 我希望我的文本框将每个值显示为用户表单中文本框中的单行 使它们看起来像项目符号列表 这可能吗 我正在考虑
  • 带有 Material ui 和 Reactjs 的嵌套侧边栏菜单

    我正在尝试使用 Material ui 开发一个侧边栏菜单 我可以制作简单的列表 在我的项目中 我需要嵌套侧边栏菜单 但我无法实现 如果我尝试使用递归函数 它仅提供主标题菜单 而不呈现子元素 请帮我开发它 嵌套侧边栏菜单的代码如下 impo