材料 UI 中的多级嵌套列表 下一个



我想创建多级嵌套列表以在左侧显示菜单 - - 与官方网站非常相似:https://material-ui-next.com/。数据源在 JSON 中,其中每个项目还有有关父项目和其他一些数据的信息 - - 这是示例:

{
    "task_number": 1201092,
    "task": "Monthly Cash Flow from Deliveries",
    "task_parent_number": 1201090,
    "task_parent": "Wholesale Cash Flow"
},
{
    "task_number": 1201095,
    "task": "Monthly Cash Flow from Fix Amounts",
    "task_parent_number": 1201090,
    "task_parent": "Wholesale Cash Flow"
},
{
    "task_number": 1201100,
    "task": "Wholesale Positions",
    "task_parent_number": 1200007,
    "task_parent": "Wholesale Contract Portfolio"
},
{
    "task_number": 1201200,
    "task": "All Wholesale Positions",
    "task_parent_number": 1201100,
    "task_parent": "Wholesale Positions"
}

我能够创建一个带有各种嵌套元素的对象 - 孩子 - 如果它们存在 followin 函数:

function getNestedChildren(arr, parent) {
  var out = [];
  for (var i in arr) {
    if (arr[i].task_parent_number == parent) {
      //console.log(i, arr[i].task_parent_number, arr[i].task_number);
      var children = getNestedChildren(arr, arr[i].task_number);
      if (children.length) {
        arr[i].children = children;
      }
      out.push(arr[i]);
    }
  }
  return out;
}

我一直在按照说明创建嵌套列表并将其导入到此处:https://material-ui-next.com/demos/lists/#nested-list

..但我无法根据需要创建带有嵌套元素的菜单..如果有人能指出我正确的方向,那就太好了。

好的,我把它结合起来,将这两个部分结合起来:

  1. 反应示例递归渲染:https://gist.github.com/nkvenom/bf7b1adfe982cb47dee3
  2. 材料列表指南在这里 - https://medium.com/@ali.atwa/getting-started-with-material-ui-for-react-59c82d9ffd93

有 mui 组件。

我在最后一个示例中添加了递归。

import type { SvgIconProps } from '@mui/material/SvgIcon';
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import TreeView, { TreeViewProps } from '@mui/lab/TreeView';
import TreeItem, { TreeItemProps, treeItemClasses } from '@mui/lab/TreeItem';
import Typography from '@mui/material/Typography';
// import DeleteIcon from '@mui/icons-material/Delete';
// import Label from '@mui/icons-material/Label';
// import SupervisorAccountIcon from '@mui/icons-material/SupervisorAccount';
// import InfoIcon from '@mui/icons-material/Info';
// import ForumIcon from '@mui/icons-material/Forum';
// import LocalOfferIcon from '@mui/icons-material/LocalOffer';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
declare module 'react' {
    interface CSSProperties {
        '--tree-view-color'?: string;
        '--tree-view-bg-color'?: string;
    }
}
type StyledTreeItemProps = TreeItemProps & {
    bgColor?: string;
    color?: string;
    labelIcon?: React.ElementType<SvgIconProps>;
    labelInfo?: React.ReactNode;
    labelText: string;
};
type RecursiveStyledTreeItemProps = StyledTreeItemProps & {
    childrenProps?: RecursiveStyledTreeItemProps[]
}
const StyledTreeItemRoot = styled(TreeItem)(({ theme }) => ({
    color: theme.palette.text.secondary,
    [`& .${treeItemClasses.content}`]: {
        color: theme.palette.text.secondary,
        borderTopRightRadius: theme.spacing(2),
        borderBottomRightRadius: theme.spacing(2),
        paddingRight: theme.spacing(1),
        fontWeight: theme.typography.fontWeightMedium,
        '&.Mui-expanded': {
            fontWeight: theme.typography.fontWeightRegular,
        },
        '&:hover': {
            backgroundColor: theme.palette.action.hover,
        },
        '&.Mui-focused, &.Mui-selected, &.Mui-selected.Mui-focused': {
            backgroundColor: `var(--tree-view-bg-color, ${theme.palette.action.selected})`,
            color: 'var(--tree-view-color)',
        },
        [`& .${treeItemClasses.label}`]: {
            fontWeight: 'inherit',
            color: 'inherit',
        },
    },
    [`& .${treeItemClasses.group}`]: {
        marginLeft: 0,
        [`& .${treeItemClasses.content}`]: {
            paddingLeft: theme.spacing(2),
        },
    },
}));
const RecursiveStyledTreeItem = ({ childrenProps, ...p }: RecursiveStyledTreeItemProps) => childrenProps
    ? <RecursiveStyledTreeItem {...p}>
        {
            childrenProps.map(cP => <RecursiveStyledTreeItem
                key={cP.nodeId}
                {...cP}
            />)
        }
    </RecursiveStyledTreeItem>
    : < StyledTreeItem {...p} />
function StyledTreeItem(props: StyledTreeItemProps) {
    const {
        bgColor,
        color,
        labelIcon: LabelIcon = null,
        labelInfo = null,
        labelText,
        ...other
    } = props;
    return (
        <StyledTreeItemRoot
            label={
                <Box sx={{ display: 'flex', alignItems: 'center', p: 0.5, pr: 0 }}>
                    {
                        LabelIcon && <Box component={LabelIcon} color="inherit" sx={{ mr: 1 }} />
                    }
                    <Typography variant="body2" sx={{ fontWeight: 'inherit', flexGrow: 1 }}>
                        {labelText}
                    </Typography>
                    {
                        labelInfo && <Typography variant="caption" color="inherit">
                            {labelInfo}
                        </Typography>
                    }
                </Box>
            }
            style={{
                '--tree-view-color': color,
                '--tree-view-bg-color': bgColor,
            }}
            {...other}
        />
    );
}
export default function CustomTreeView({ treeViewProps, items }: {
    treeViewProps: Partial<TreeViewProps>
    items: RecursiveStyledTreeItemProps[]
}) {
    return (
        <TreeView
            // defaultExpanded={['3']}
            defaultCollapseIcon={<ArrowDropDownIcon />}
            defaultExpandIcon={<ArrowRightIcon />}
            defaultEndIcon={<div style={{ width: 24 }} />}
            sx={{ height: 264, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
            {...treeViewProps}
        >
            {items.map(item => <RecursiveStyledTreeItem
                key={item.nodeId}
                {...item}
            />)}
        </TreeView>
    );
}

有梅树选择

最新更新