react递归方法实现配置化菜单栏

291 阅读2分钟

前言

最近在学习react,想着之前vue用递归组件实现了配置化的菜单栏,那么是否可以用react也实现一次呢?毕竟react一个函数就是一个组件(虽然vue最终注册为组件时也是函数,但是vue-loader处理后的其实就是一个对象)。心动不如行动,下面我们就用react实现一次~

一、分析

其实相对于vue,react的递归更容易理解,实质上就是一个简单的递归函数。首先,选择主流的antd组件库作为我们的UI,避免重复繁琐的工作;然后,我们需要思考配置的数据结构,与路由router类似,是一个嵌套的数组对象结构,我们需要就是递归遍历这个数组。

二、实现

递归函数

import React from "react";
import { menuList } from './config'

type MenuItem = Required<MenuProps>['items'][number];// menuItem类型
// antd方法,用于返回menuItem需要的字段
function getItem( label: React.ReactNode, key: React.Key, icon?: React.ReactNode, children?: MenuItem[], type?: 'group'): MenuItem {
    return {
      key,
      icon,
      children,
      label,
      type,
    } as MenuItem;
}
interface item {
    key: string,
    icon: string,
    children: item[],
    label: string,
    type: string,
}
function getMenuList() {
    let tempMenuList: ItemType[] = [];
    let openKeys:string[] = [];
    const getList = (list:any, newList: MenuItem[]) => {
        for(let i=0; i<list.length; i++) {
            const { value, label, icon } = list[i] || {};
            const it = getItem(label, value || label);
            newList.push(it)
            routeMap[value] = label
            if(tempBo) {
                const tempItem = newList[i] as item
                tempItem.children = [];
                getList(list[i].children || [], tempItem.children);
            }
        }
    }
    getList(menuList, tempMenuList)
    return {tempMenuList}
}

const MyMenu:React.FC<{bread:breadType}> = (props) => {
    const { tempMenuList } = getMenuList()
    return (
        <Menu
            style={{width:256, height:'100%'}}
            mode="inline"
            items={tempMenuList}
        ></Menu>
    )
}

config配置菜单栏

export const menuList = [
    {
        value: '/home',
        label: '首页',
    },
    {
        value: '/form',
        label: '表单系列',
        children: [
            {
                value: '/form/loopForm',
                label: '循环表单及校验'
            }
        ]
    },
    {
        value: '/components',
        label: '封装组件',
        children: [
            {
                value: '/components/inherit',
                label: '二次封装组件功能透传'
            },
            {
                value: '/components/table',
                label: 'table组件',
            }
        ]
    },
    {
        value: '/skill',
        label: '奇技淫巧',
    }
]

效果

以上就实现了简单的配置化菜单栏了

image.png

三、总结

相较于vue的递归组件实现配置化菜单栏,react会更方便写,毕竟写递归函数相较而言会更容易上手。除了简单的配置菜单栏的label,其实也可以增加一些icon,路由等效果。

github地址:github.com/qiangguangl…

下期预告:

既然实现了配置化的菜单栏,如果想在项目中使用的话,肯定需要有一套路由管理系统了~ 下一期就引入react-router实现路由管理,顺便增加一些样式(增加icon配置~)