antd菜单使用动态图标

antd的MenuItem的icon属性值是一个ReactNode类型值,如果我们项目的菜单比较少,且是静态配置的话,倒还好,简单配置一下就好了,可大多数情况都不是简单的几个固定的菜单,而是从接口下发的带有权限菜单,那么这个时候就就麻烦了。

因为正常情况下,接口下发的菜单数据大概的数据结构应该类似:

[
  {
    "id": 1,
    "path": "/orderList",
    "text": "订单列表",
    "icon": "BarChartOutlined"
  },
  {
    "id": 2,
    "path": "/report",
    "text": "商品管理",
    "icon": "CameraOutlined"
  }
]

我们直接获取到的icon字段是一个字符串类型的,显然不符合antd中Menu.Item中icon属性值的类型要求,那怎么办呢?

既然icon属性需要一个ReactNode类型,那么我们就创建一个ReactNode类型吧.

// 创建icon图标元素
const iconToElement = (name: string) =>
    React.createElement(Icon && (Icon as any)[name], {
        style: { fontSize: '16px' }
    })

这样,我们就可以在Menu.Item中去使用了:

<Menu.Item key={item.path} icon={item.icon ? iconToElement(item.icon) : ""}>
    <Link to={item.path}>{item.text}</Link>
</Menu.Item>

当然了,我们在使用图标之前,需要先把图标库引入进来(假设我们使用的就是antd的默认图标库):

import * as Icon from "@ant-design/icons";

这样,就具有正常的使用接口下发的指定的icon了。

为了方便理解,贴一个整个的代码吧,有些代码是测试的,没有清理,凑合看下吧:

import React, { FC, useEffect, useState } from 'react';
import { Layout, Menu } from "antd";
import * as Icon from "@ant-design/icons";
const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;
import request from 'umi-request';
import logo from "../../assets/images/logo.png";
import style from "./less/layout2.less";
import { Link } from 'umi';


const MainLayout: FC = (props) => {
    const [menu, setMenu] = useState([]);
    const [defaultOpenKey, setDefaultOpenKey] = useState([]);
    const getMenu = () => {
        request.get("http://localhost:3000/menu").then(function (res) {
            setDefaultOpenKey(res.defaultOpenKey);
            setMenu(res.data);
        }).catch(err => {
            console.log(err);
        })
    }
    useEffect(() => {
        getMenu();
    }, []);

    // 创建icon图标元素
    const iconToElement = (name: string) =>
        React.createElement(Icon && (Icon as any)[name], {
            style: { fontSize: '16px' }
        })

    return <div>
        <Layout>
            <Header className={style.header}>
                <div className={style.logo}>
                    <img src={logo} alt="logo" />
                </div>
            </Header>
            <Layout>
                <Sider width={200} className="site-layout-background" theme="light">
                    <Menu mode='inline' defaultSelectedKeys={defaultOpenKey} defaultOpenKeys={defaultOpenKey} theme="light">
                        {
                            menu.map((item: any) => {
                                if (item.children && item.children.length > 0) {
                                    return <SubMenu key={item.path} title={item.text} icon={item.icon ? iconToElement(item.icon) : ""}>
                                        {
                                            item.children.map((citem: any) => {
                                                return <Menu.Item key={citem.path} icon={citem.icon ? iconToElement(citem.icon) : ""}>
                                                    <Link to={citem.path}>{citem.text}</Link>
                                                </Menu.Item>
                                            })
                                        }
                                    </SubMenu>
                                } else {
                                    return (<Menu.Item key={item.path} icon={item.icon ? iconToElement(item.icon) : ""}>
                                        <Link to={item.path}>{item.text}</Link>
                                    </Menu.Item>
                                    )
                                }
                            })
                        }
                    </Menu>
                </Sider>
                <Layout className={style.maincontentWraper}>
                    <Content className={style.maincontent} style={{ minHeight: '90vh' }}>
                        {props.children}
                    </Content>
                </Layout>
            </Layout>
        </Layout>
    </div>
}

export default MainLayout;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 要设置动态菜单,你需要在 Ant Design Pro 中使用路由配置来定义你的菜单。在路由配置中,你可以为每个页面定义一个菜单项,并且可以根据需要设置它们的子菜单。 以下是一个简单的例子,展示如何使用路由配置来设置动态菜单: ```javascript // src/config/router.config.js export default [ { path: '/dashboard', name: 'Dashboard', icon: 'dashboard', component: './Dashboard', }, { path: '/users', name: 'Users', icon: 'user', component: './Users', }, { path: '/settings', name: 'Settings', icon: 'setting', routes: [ { path: '/settings/profile', name: 'Profile', component: './Profile', }, { path: '/settings/account', name: 'Account', component: './Account', }, ], }, ]; ``` 在上面的配置中,我们定义了三个顶级菜单项:Dashboard、Users 和 Settings。Settings 菜单项有两个子菜单项:Profile 和 Account。 然后,我们需要将这些路由配置传递给 ProLayout 组件,该组件将渲染菜单和其他布局元素: ```javascript // src/layouts/BasicLayout.js import ProLayout from '@ant-design/pro-layout'; import routerConfig from '../config/router.config'; export default function BasicLayout(props) { return ( <ProLayout route={routerConfig} location={props.location} {...props} > {props.children} </ProLayout> ); } ``` 在上面的代码中,我们将路由配置传递给 ProLayout 组件,并将其设置为 `route` 属性的值。这将告诉 ProLayout 组件如何渲染你的菜单。 现在,你可以在你的页面组件中访问 `menuData` 属性,该属性包含有关当前菜单的信息。例如,你可以使用 `menuData` 属性来确定哪个菜单项当前处于活动状态: ```javascript // src/pages/Dashboard.js import { useLocation } from 'umi'; export default function Dashboard() { const location = useLocation(); const activeMenu = location.pathname; return ( <div> <h1>Dashboard</h1> <p>Active menu: {activeMenu}</p> </div> ); } ``` 在上面的例子中,我们使用 `useLocation` 钩子来获取当前页面的位置,并使用它来确定哪个菜单项当前处于活动状态。 ### 回答2: antdpro是一款基于Ant Design的React前端开发框架,可以用来快速搭建UI界面和管理系统。设置动态菜单是指根据用户权限或其他条件,在页面加载时动态生成菜单项。 首先,我们需要从后端获取用户的权限信息或菜单数据。可以通过接口请求获取数据或在登录时将数据存储在本地。 接下来,在Ant Design Pro框架中,可以在config目录下的menu.js文件中配置菜单。这个文件可以定义路由、菜单项等信息。在这个文件中,可以使用JavaScript的语法来动态生成菜单项。 例如,可以使用.map()方法遍历权限数据或菜单数据,并根据数据生成菜单项。根据数据的结构,可以设置菜单项的标题、路径、图标等属性。可以根据数据中是否有子菜单的字段,来判断是否需要生成子菜单项。 在菜单项的路径配置中,可以使用动态路由的方式,将菜单项和具体的页面组件相对应。这样,当用户点击菜单项时,就可以跳转到对应的页面。 然后,在布局组件(通常是BasicLayout)中,可以根据菜单的配置信息,使用Ant Design Pro提供的Menu组件来渲染菜单。可以根据路由信息,自动高亮显示当前页面对应的菜单项。 最后,在菜单配置完成后,就可以启动项目,访问页面,就能看到动态生成的菜单了。根据用户的权限或其他条件,在页面加载时,会根据菜单配置自动显示对应的菜单项。 总结起来,通过配置菜单数据,使用Ant Design Pro提供的组件来渲染菜单,再根据用户权限或其他条件动态生成菜单项,就可以实现antdpro设置动态菜单的功能。 ### 回答3: 在antdpro中设置动态菜单需要以下步骤: 1. 定义菜单数据:首先,我们需要定义菜单的数据结构。菜单可以使用树形结构,每个节点包含菜单项的信息,比如菜单名称、图标、路由等。 2. 获取菜单数据:接下来,我们需要从后端获取菜单数据。可以使用Ajax或者Fetch等方式从后端获取菜单数据。 3. 将菜单数据存储到状态中:获取到菜单数据后,我们需要将数据存储到React组件的状态中。可以使用useState或者useReducer等Hooks来管理菜单数据的状态。 4. 渲染动态菜单:在组件的渲染方法中,使用遍历函数(如map)将菜单数据映射到菜单组件中。antdpro提供了Menu和SubMenu两个组件来渲染菜单结构。可以根据菜单数据的层级关系来嵌套使用这两个组件。 5. 添加路由和点击事件:对于菜单中的每个菜单项,我们通常需要添加路由和点击事件。可以使用React Router来定义路由,同时在点击事件中也可以使用history.push()来实现路由跳转。 6. 权限管理:动态菜单通常还需要与用户的权限管理相结合。可以根据用户的角色或权限设置不同的菜单项显示或隐藏。可以在渲染菜单时,通过条件判断来控制菜单项的显示与隐藏。 以上就是在antdpro中设置动态菜单的大致步骤。通过定义菜单数据、获取菜单数据、存储菜单数据、渲染动态菜单以及添加路由和点击事件等步骤,我们可以实现一个灵活、可扩展的动态菜单功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值