React后台管理系统09 菜单组件的抽取
阅读原文时间:2023年08月31日阅读:1

修改Home.tsx的内容:将主菜单的内容进行抽离,然后单独引入=>MainMenu

import { Breadcrumb, Layout, Menu } from 'antd';
import React, { useState } from 'react';
import { Outlet } from 'react-router-dom';
import MainMenu from "@/components/MainMenu";
const { Header, Content, Footer, Sider } = Layout;

const View: React.FC = () => {
    const [collapsed, setCollapsed] = useState(false);

    return (
        <Layout style={{ minHeight: '100vh' }}>
            {/* 左边侧边栏 */}
            <Sider collapsible collapsed={collapsed} onCollapse={value => setCollapsed(value)}>
                <div className="logo" />
                <MainMenu></MainMenu>
            </Sider>
            {/* 右边的内容 */}
            <Layout className="site-layout">
                {/* 头部 */}
                <Header className="site-layout-background" style={{ paddingLeft: '16px' }} >
                    <Breadcrumb style={{ lineHeight: '64px' }}>
                        <Breadcrumb.Item>User</Breadcrumb.Item>
                        <Breadcrumb.Item>Bill</Breadcrumb.Item>
                    </Breadcrumb>
                </Header>
                {/* 右边内容-白色底的盒子 */}
                <Content style={{ margin: '16px 16px 0' }} className="site-layout-background">
                    {/* 窗口部分 */}

                    <Outlet />
                </Content>
                {/* 右边底部 */}
                <Footer style={{ textAlign: 'center', padding: 0, lineHeight: '48px' }}>Ant Design 2018 Created by Ant UED</Footer>
            </Layout>
        </Layout>
    );
};

export default View;

在components文件夹中进行抽离Menu:

import {
    DesktopOutlined,
    FileOutlined,
    PieChartOutlined,
    TeamOutlined,
    UserOutlined,
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
import React, { useState } from 'react';
import { Menu } from 'antd';
import { To, useNavigate } from 'react-router-dom';

type MenuItem = Required<MenuProps>['items'][number];

function getItem(
    label: React.ReactNode,
    key: React.Key,
    icon?: React.ReactNode,
    children?: MenuItem[],
): MenuItem {
    return {
        key,
        icon,
        children,
        label,
    } as MenuItem;
}

const items: MenuItem[] = [
    getItem('Option 1', '/page1', <PieChartOutlined />),
    getItem('Option 2', '/page2', <DesktopOutlined />),
    getItem('User', 'page3', <UserOutlined />, [
        getItem('Tom', '3'),
        getItem('Bill', '4'),
        getItem('Alex', '5'),
    ]),
    getItem('Team', 'page4', <TeamOutlined />, [getItem('Team 1', '6'), getItem('Team 2', '8')]),
    getItem('Files', 'page5', <FileOutlined />),
];

// 组件内部
const Comp: React.FC = () => {

    const navigateTo = useNavigate();

    const menuClick = (e: { key: String }) => {
        console.log('点击了菜单', e.key);
        // 点击菜单就跳转到对应的路由  编程式导航跳转,利用到一个Hook
        navigateTo(e.key as To)
    }

    const [openKeys, setOpenKeys] = useState(['']);

    const handleoOpenChange = (keys: string[]) => {
        // keys是一个数组,记录了当前哪一项是展开的,使用key来进行记录
        // 展开才菜单的时候就会执行这里的代码
        // 把这个数组修改为最后一项,因为只要一项是展开的,就是我刚刚点击的那一项
        setOpenKeys([keys[keys.length - 1]])
        console.log("@展开的项" + keys);
    }
    return (
        <Menu
            theme="dark"
            defaultSelectedKeys={['/page1']}
            // 处理菜单展开和回收的方法
            onOpenChange={handleoOpenChange}
            mode="inline"
            // items 就是菜单项的数据
            items={items}
            onClick={menuClick}
            // 当前菜单展开项的key数组
            openKeys={openKeys}
        />
    )
}

export default Comp;