React + Antd Menu组件实现菜单树

准备好两个变量,一个用来保存平级菜单列表,一个用来保存遍历后的菜单树。
推荐后端返回平级菜单树,假如菜单比较多,可以直接结合find方法找到菜单,做搜索功能很省事。

 const [menuList, setMenuList] = useState([]);

 const [treeMenuList, setTreeMenuList] = useState([]);

如果后端返回的是平级菜单树,则需要转化成树形结构,注意利用JSON方法进行深度克隆一下,防止影响原有数据

const treeList: any = listTransToTreeData(JSON.parse(JSON.stringify(userInfo.menus)), 'jd_dm', 'fjd_dm', 'children');

listTransToTreeData方法如下:

/**
 * 平级结构转树形结构
 *
 * 示例:const jsonDataTree = listTransToTreeData (jsonData, 'id', 'pid', 'chindren');
 * @param list 平级数据列表
 * @param idStr id的字符串
 * @param pidStr 父id字符串
 * @param chindrenStr children的字符串
 */
export const listTransToTreeData = (list: any, idStr: string, pidStr: string, chindrenStr: string) => {
  let r = [], hash: any = {}, id = idStr, pid = pidStr, children = chindrenStr, i = 0, j = 0, len = list.length;
  for (; i < len; i++) {
    hash[list[i][id]] = list[i];
  }
  for (; j < len; j++) {
    let aVal = list[j], hashVP = hash[aVal[pid]];
    if (hashVP) {
      !hashVP[children] && (hashVP[children] = []);
      hashVP[children].push(aVal);
    } else {
      r.push(aVal);
    }
  }
  return r;
}

准备一个递归生成菜单树的方法

  const getTreeMenu = (menuData: any) => {
    if (menuData.length > 0) {
      return menuData.map((item: any) => {
        if (item.children && item.children.length > 0) {
          return <SubMenu key={item.jd_dm} title={item.jd_mc} icon={<i className={`iconfont icon-${item.jd_icon}`}/>}>
                  {getTreeMenu(item.children)}
                </SubMenu>
        }
        return (
          <Menu.Item key={item.jd_dm}>{item.jd_mc}</Menu.Item>
        )
      })
    }
  }

DOM结构如下

<Menu onClick={menuHandleOk} mode="horizontal"
        style={{ width: 500, paddingTop: 12, height: 65 }} selectedKeys={selectedKeys}>
    { getTreeMenu(treeMenuList) }
  Menu>

绑定的onclik事件

  const menuHandleOk = (e: any) => {
    const find: any = menuList.find((item: any) => item.jd_dm === e.key);
    console.log('menuItem', find);
  }

你可能感兴趣的:(react.js,javascript,前端)