递归实现的方法,通过是否包含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>;
关于递归遍历,这篇文章讲的很细致可以参考:递归遍历的讲解