react项目自定义svg图标

370 阅读1分钟

react项目自定义svg图标

react 项目开发中,我们常使用一些字体图标来进行展示,但是有些时候并不能找到合适的字体图标,所以会找 ui 设计帮我们设计并导出一些 svg 图标,有的方案是将 svg 图标在IcoMoon网站转换为字体图标,然后再项目中使用,这个方案可行但是较为麻烦。所以我们采用第二种方案,直接应用 svg 图标。

  • 第一步安装 vite-plugin-svg-icons 插件
pnpm i vite-plugin-svg-icons -D
  • 第二步 vite.config.js 中进行配置
// 自定义svg图标
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';

// vite插件
const plugins = [
    react(),
    createSvgIconsPlugin({
        // 指定要缓存的图标文件夹
        iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
        // 执行icon name的格式
        symbolId: 'icon-[name]',
    }),
];
  • 第三步 封装 svgIcon 组件(目前将组件iconsvgIcon封装在一起,方便使用)
import propTypes from 'prop-types';
import Icon, * as ElIconsModules from '@ant-design/icons';
import { svgIcons, ElIcons } from '@u/icons';

/***
 * 图标组件
 * @module components/my-icon
 */
const MyIcon = ({ icon, ...props }) => {
    /***************************ElIcon组件********************************/
    const ElIconsShow = !!ElIcons.find((item) => item === icon);
    if (ElIconsShow) {
        return <Icon {...props} component={ElIconsModules[icon]} />;
    }

    /***************************自定义svg组件********************************/
    const svgIconsShow = !!svgIcons.find((item) => item === icon);
    if (svgIconsShow) {
        return (
            <span role="img" className="anticon" {...props}>
                <svg viewBox="0 0 1024 1024" width="1em" height="1em" fill="currentColor">
                    <use href={`#icon-${icon}`} />
                </svg>
            </span>
        );
    }
};

MyIcon.propTypes = {
    icon: propTypes.string,
};

export default MyIcon;
/********两种图标的数据生成*** '@u/icons' ******************/
import * as ElIconsModules from '@ant-design/icons';

const svgIcons = [],
    ElIcons = [];
// svg图标
const svgModules = import.meta.glob('@/assets/svg/*.svg');
for (const key of Object.keys(svgModules)) {
    svgIcons.push(key.replace(/[./assets/svg/|.svg]/g, ''));
}
// ui图标
for (const key of Object.keys(ElIconsModules)) {
    ElIcons.push(key);
}

export { svgIcons, ElIcons };