React中搭建Svg组件,动态引用Svg文件并配置

312 阅读2分钟

背景

最近在开发项目的过程中,某些场景中有过多的Svg图标导入引用,在业务层中嵌入Svg代码十分不美观,而且通过fill去修改颜色容易使后续迭代难度升级,于是便从基础架构中重新设置Svg

实现

使用Webpack5中提供的require.context建立组件与外部文件的上下文,然后再通过svg中的use标签动态导入到业务层,代码如下:

import React from 'react';
let importAll = requireContext => requireContext.keys().forEach(requireContext)

try {
    importAll(require.context('@/asset/svg', true, /\.svg$/));
} catch (error) {
    console.log(error);
}

const SvgIcon = ({
    name = '',
    ...restProps
}) => {
    return (
        <svg {...restProps}>
            <use xlinkHref={`#${name}`} />
        </svg>
    );
};

export default SvgIcon;

注意:该方法对Webpack强依赖,如果是别的请使用基础框架里提供的context进行资源连接

由于在业务层中需要经常处理svg图标的颜色转换,但是UI给出的Svg文件一般是自带fill的,所以这里需要通过svgo这个插件来实现svg文件的处理

// 使用svgo-loader时需要下载,通过 npm i svgo-loader -D,然后使用其自带的默认插件进行svg文件处理
// svgo-loader只是对文件进行处理,还需要svg-sprite-loader来处理其结果转换为可被webpack接收的result
// 这里也可以利用svg-sprite-loader官网提供的配置进行个性化配置
{
    test: /\.svg$/,
        use: [
            { loader: 'svg-sprite-loader', options: {} },
            {
                loader: 'svgo-loader', options: {
                    plugins: [  // 使用插件默认删除自带的颜色,由业务层自主控制
                        {
                            name: "removeAttrs",
                            params: {
                                attrs: 'fill',
                                elemSeparator: ":",
                                preserveCurrentColor: false
                            }
                        }
                    ]
                }
            }
        ]
}

结论

svg对比传统的png和jpg图片而言,具有以下优点:

  1. 矢量格式可呈现任何大小而不降低其质量
  2. 格式具有高度可压缩性和轻量级
  3. 样式上支持透明度,动态图像等
  4. 能够在代码或者文本编辑器中创建简单的svg渲染而无需UI专门切图

png等传统图片也并非一无是处,而是在绝大部分场景下Svg更加利于图标方面的控制与开发,在对项目进行架构设置时,我更加推荐将其添加进来,将svg资源与图片资源区别分割开来