递归实现多级菜单遍历,附antd的menu实现方案

递归实现的方法,通过是否包含children决定是否需要递归调用

/**
 *
 * @param { 路由列表 } data
 * @param { 从地址栏获取的路由 } pathKey
 * openKey是添加的是否展开父菜单的参数
 */
const initKey = (data, pathKey) => {
  const list = [];
  const key = null;
  const getList = data => {
    data.map(item => {
      if (item.children && item.children.length) {
        const children = item.children.map(subItem => {
          return { ...subItem, openKey: item.name };
        });
        getList(children); // 递归调用
      } else {
        let newItem = { ...item };
        if (!Object.prototype.hasOwnProperty.call(item, 'openKey')) {
          newItem = { ...item, openKey: item.name };
        }
        list.push(newItem);
      }
    });
  };

  getList(data);
  console.log(list);
  const filtered = list.find(item => item.path === pathKey);
  console.log('filtered', filtered);
  if (filtered) {
    const key = filtered.name;
    return key;
  }
  return key;
};

调用过程

const data = [
  {
    name: '菜单1',
    path: '/menu1',
    children: [
      {
        name: '子菜单1',
        path: '/menu1',
      },
      {
        name: '子菜单1',
        path: '/menu2',
      },
    ],
  },
  {
    name: '菜单2',
    path: '/menu3',
    children: [
      {
        name: '子菜单3',
        path: '/menu3',
        children: [
          {
            name: '孙子菜单1',
            path: '/menu3',
          },
        ],
      },
      {
        name: '子菜单4',
        path: '/menu4',
      },
      {
        name: '产品多维看板',
        path: '/menu5',
      },
    ],
  },
  {
    name: '菜单3',
    path: '/menu6',
  },
];
const pathKey = '/menu3';
console.log(1, initKey(data, pathKey));

附: antd的menu实现

export default function WrappedLink({ to, ...rest }) {
  return <Link to={to} {...rest} />;
}
/**
 * 用于antd menu
 * defaultOpenKeys代表需要默认展开的菜单,selectedKeys代表选中的菜单
 */
<Menu
  mode="inline"
  defaultOpenKeys={[keyObj.openKey]}
  selectedKeys={[keyObj.key]}
  style={{ height: '100%', borderRight: 0 }}
>
  {data &&
    data.map(item =>
      item.children ? (
        <SubMenu key={item.name} title={item.name} icon={item.iconType}>
          {item.children &&
            item.children.map(child => (
              <Menu.Item key={child.name}>
                <WrappedLink to={child.path}>{child.name}</WrappedLink>
              </Menu.Item>
            ))}
        </SubMenu>
      ) : (
        <Menu.Item key={item.name}>
          {item.iconType}
          <WrappedLink to={item.path}>{item.name}</WrappedLink>
        </Menu.Item>
      )
    )}
</Menu>;

关于递归遍历,这篇文章讲的很细致可以参考:递归遍历的讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值