在React中使用动态图标

背景

需要按名称引入图标

安装

yarn add react-icons

实现

typescript 复制代码
import loadable from "@loadable/component"
import { IconBaseProps, IconType } from "react-icons/lib"

interface typesPropsIcon {
  nameIcon: string;
  propsIcon?: IconBaseProps
}

export function Icon({ nameIcon, propsIcon }: typesPropsIcon): JSX.Element {
  const lib = nameIcon.replace(/([a-z0-9])([A-Z])/g, '$1 $2').split(" ")[0].toLocaleLowerCase();
  const ElementIcon: IconType = loadable(() => import(`react-icons/${lib}/index.js`), {
    resolveComponent: (el: JSX.Element) => el[nameIcon as keyof JSX.Element]
  });

  return (<span style={{paddingRight: 6}}><ElementIcon {...propsIcon} style={{size: '1em'}}/></span>)

示例

typescript 复制代码
<Space direction="horizontal">
      <Menu
        mode="inline"    
        style={{ width: 500, height:'fit-content' }}    
        items={[
          { key: 'mail', label: 'Mail1', icon: <MailOutlined />, type:'group' },
          { key: 'mail2', label: 'Mail2', icon: <Icon nameIcon="AiFillBug" propsIcon={{ size: 20 }} /> },
          { key: 'mail3', label: 'Mail3', icon: <Icon nameIcon="AiFillInsurance" propsIcon={{ size: 20 }}/> },
          { key: 'mail4', label: 'Mail4', icon: <Icon nameIcon="AiFillDollarCircle" propsIcon={{ size: 20 }}/> },
          { key: 'mail5', label: 'Mail5', icon: <Icon nameIcon="AiOutlineApartment" propsIcon={{ size: 20 }}/> },
        ]}        
      />      
      <Menu
        mode="inline" 
        style={{ width: 256, height:'fit-content', marginLeft: 4}}          
        items={[
          { key: 'mail11', label: ' Mail1', icon: <Icon nameIcon="BiAperture" propsIcon={{ size: 20 }}/>, type:'group' },
          { key: 'mail21', label: ' Mail2', icon: <Icon nameIcon="CiBasketball" propsIcon={{ size: 20 }}/> },
          { key: 'mail31', label: ' Mail3', icon: <Icon nameIcon="CiBadgeDollar" propsIcon={{ size: 20 }}/> },
          { key: 'mail41', label: ' Mail4', icon: <Icon nameIcon="CiBoxList" propsIcon={{ size: 20, marginRight: 80, marginBottom: 10 }}/> },
          { key: 'mail51', label: ' Mail5', icon: <ClusterOutlined /> },
        ]}        
      />      
      </Space>
相关推荐
翻滚吧键盘7 分钟前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
苦夏木禾12 分钟前
js请求避免缓存的三种方式
开发语言·javascript·缓存
超级土豆粉20 分钟前
Turndown.js: 优雅地将 HTML 转换为 Markdown
开发语言·javascript·html
秃了也弱了。26 分钟前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
乆夨(jiuze)1 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
忧郁的蛋~1 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中1 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互
然我1 小时前
别再只用 base64!HTML5 的 Blob 才是二进制处理的王者,面试常考
前端·面试·html
NanLing2 小时前
【纯前端推理】纯端侧 AI 对象检测:用浏览器就能跑的深度学习模型
前端
呆呆的心2 小时前
前端必学:从盒模型到定位,一篇搞定页面布局核心 🧩
前端·css