IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> antd菜单使用动态图标 -> 正文阅读

[JavaScript知识库]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;

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:27:56  更:2022-03-22 20:29:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:23:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码