大量 SVG 图标在 React 中的极速集成与应用

1. 背景

在一些业务场景中,可能需要使用一些业务上自定义的图标,而这些业务图标消费起来需要很多重复的流程和样板代码,用多了很繁琐。

大致流程:

Sketch svg 导出 ➡️ 压缩 svg ➡️ 纯色图标 currentColor 覆写 ➡️ 上传 svg 供 img 消费 OR svg 引入 React ➡️ svg React 组件样板代码编写 ➡️ -.125em 对齐处理 ➡️ 纯色图标 mask 处理 ➡️ 消费导入

可以看到当自定义的 svg 过多时,处理起来很繁琐。

期待效果,尽量减少 SVG 样板代码的编写,减少特殊样式的注入,减少 import 及 减少网络请求。

2. 实现

下面有两种实现方式,一种是纯色的 font 化,一种是通过编写工具读取配置文件自动生成。

2.1 实现一:font 化

对于纯色图标将所有 svg 创建一个单独的字体文件实现。

流程生成大致如下:

// ...
const svgData = fs.readFileSync(svgFile, "utf-8");// 解析 SVG 文件
const svgTree = svgParser.parse(svgData);// 提取路径数据
const paths = svgTree.children.filter((node) => node.tagName === "path");
const pathData = paths.map((path) => path.properties.d);// 创建字体对象
const font = FontCarrier.create();// 添加字形
pathData.forEach((data, index) => {const glyph = font.createGlyph();glyph.path(data);font.setGlyph("icon" + index, glyph);
});// 生成字体文件
const fontBuffer = font.output();
// ...

生成兼容全平台字体样式:

@font-face {font-family: "xadmin";src: url("fonts/xadmin.woff?pf1byw") format("woff"), /* WOFF 字体格式优先 */url("fonts/xadmin.eot?pf1byw#iefix") format("embedded-opentype"),/* IE9 Compat Modes */ url("fonts/xadmin.ttf?pf1byw") format("truetype"), /* Safari, Android, iOS */url("fonts/xadmin.svg?pf1byw#xadmin") format("svg"); /* Legacy iOS */font-weight: normal;font-style: normal;font-display: block;
}

这边建议 WOFF 字体优先,WOFF 是为 Web 设计的字体格式,WOFF 内置了字体的压缩,会有比 TTF/OTF 更小的文件体积,浏览器兼容性在 98% 左右。

字体加载过程中会发生偏移问题,这里可以通过设置 font-display: optional 来减少 CLS 问题。
由于浏览器解析 @font-face 定义后并不会下载字体,而是在构建 render tree 时发现有非空节点在使用该字体时才会触发字体的下载,所以字体文件需要通过 preload 进行提前加载,如果将 font 文件放在 CDN 还需要加入 crossorigin="anonymous" 来实现不同源的资源可以被缓存在浏览器中,并在不同网站之间共享。

在 TS 场景下为了更快速的活的提示,可以对 i 进行重新定义自动生成 icon.d.ts:

namespace JSX {interface IntrinsicElements {i: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>,HTMLElement> & {className?:| "icon-info"| "icon-send"| "icon-bread-delimiter"| "icon-copy"| "icon-terminal-folder"| "icon-terminal-all"| "icon-one"| "icon-lock"| "icon-edit"| "icon-delete";};}
}
  • 优势:
    • 只需要在入口引入一个样式文件即可。
    • 消费时不需要任何 import 语句,直接消费 i 元素即可,且具备完成的 icon 代码提示。
    • 变色场景仅需要修改 color 属性。
  • 不足:
    • 彩色图标有兼容问题,所以仅适合纯色图标。
    • 无法按需导入,引能全量(纯单个业务场景可以忽略)。
    • 简单 svg 比 font 的渲染性能更好。

2.2 实现二:工具自动化 svg

如何使用 svg 的全部优势,无论纯色还是彩色的都可正常使用,且减少样板代码及缩短链路呢?

比较直接的方式就是工具化,读取一个配置文件实现全链路,消费的时候仅 import 一下就可以了。

于是写了下面这个工具。

2.2.1 svg 纯色可修改实现

这里有两种方式,一种是修改 svg 代码,将所有 fill 进行替换,修改为 currentColor,在外层直接设置 color 即可。

<path d="M7 1.75a....25v-.375a.25.25 0 0 1 .25-.25h.375Z" fill="currentColor" />

另一种采用蒙板方式实现,将背景极与蒙板图片合成,并将背景色指定为 color 颜色:

-webkit-mask: url("data:image/svg+xml,...C%2Fsvg%3E") no-repeat;
mask: url("data:image/svg+xml,...C%2Fsvg%3E") no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
background-color: currentColor;
2.2.2 svg 对齐问题

这里统一使用 background 处理,使用时指定宽高即可。

彩色 svg 处理:

background: url("data:image/svg+xml,...C%2Fsvg%3E") no-repeat;
background-size: 100% 100%;
background-color: transparent;
2.2.3 组件化

直接根据配置文件聚合生成到一个 TSX 中即可,如下:

import React, { FC } from "react";type TProps = {className?: string;style?: React.CSSProperties;
};export const Icongoal: FC<TProps> = ({ className, style = {} }) => (<divstyle={{background:'url("data:image/svg+xml,%3Csvg...%3E%3C%2Fsvg%3E") no-repeat',backgroundSize: "100% 100%",backgroundColor: "transparent",width: "1em",height: "1em",...style,}}className={className}/>
);export const Iconlocak: FC<TProps> = ({ className, style = {} }) => (<divstyle={{mask: 'url("data:image/svg+xml,%3Csvg%...3C%2Fsvg%3E") no-repeat',WebkitMask: 'url("data:image/svg+xml,%3Csvg%...vg%3E") no-repeat',backgroundColor: "currentColor",WebkitMaskSize: "100% 100%",maskSize: "100% 100%",width: "1em",height: "1em",...style,}}className={className}/>
);
// ...
2.2.4 压缩填充处理

将前置流程进行处理,并移除与 React 冲突的 class:

optimize(item.content, {plugins: [{ name: "removeAttrs", params: { attrs: "class" } },{name: "preset-default",},{name: "fill-currentColor",fn: () => {return {element: {enter: (node) => {if (node.attributes.fill == null ||node.attributes.fill == "" ||node.attributes.fill == "none") {return;}node.attributes.fill = "currentColor";},},};},},],
});
2.2.5 配置文件
module.exports = {// 有色 svg 列表colorIcon: [{// 名称name: "goal",// svg 内容content: `<?xml version="1.0" encoding="UTF-8"?>`,},],// 单色 svg 列表solidColorIcon: [{name: "lock",content: `<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M0 0h16v16H0z"/><path d="M10.5 6.3v-1a2.5 2.5 0 0 0-5 0v1h5zm1.5 1H4v6h8v-6zM9.75 9.8a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-3.5a.25.25 0 0 1-.25-.25v-.5a.25.25 0 0 1 .25-.25zM4.5 5.3a3.5 3.5 0 0 1 7 0v1h.5a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h.5v-1z" fill="#0D5DFF" class="fill-line"/></g></svg>`,},],// 从文件夹读取彩色 svg 文件colorIconDirPath: "./",// 从文件夹读取单色 svg 文件solidColorIconDirPath: "./",// React 组件 TSX 导出目录output: "./dist",// React 组件前缀compoentPrefix: "Icon",
};
2.2.6 预览图标

未避免见名不知图的问题,会自动生成图标的预览页面,可参考使用。

  • 优势:
    • 链路缩短,一键生成。
    • 支持单色/彩色 svg。
    • 按需加载、构建。
    • 减少网络请求,提升渲染性能。
  • 不足:
    • 过多时会增加打包体积。

Github 项目地址
Github 原文地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/195485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拼多多商品价格监控自动化API接口获取拼多多商品详情数据API接口

随着电子商务的飞速发展&#xff0c;越来越多的人选择在网上购物。在这个充满竞争的市场中&#xff0c;拼多多以其独特的商业模式和创新的营销手段&#xff0c;迅速崛起成为中国领先的电商平台之一。为了更好地满足消费者的需求&#xff0c;拼多多提供了丰富的API接口&#xff…

JavaScript的创建对象时的语法糖

js中创建一个自定义对象有两种方法&#xff0c;一种是使用new&#xff0c;另一种是使用对象字面量形式&#xff08;即直接构建&#xff0c;关于字面量详见https://blog.csdn.net/bigcarp/article/details/134777091&#xff09; 使用对象字面量定义对象时&#xff0c;若对象的…

统信UOS_麒麟KYLINOS配置apt及git内网代理

原文链接&#xff1a;统信UOS/麒麟KYLINOS上配置APT和GIT内网代理 **hello&#xff0c;大家好啊&#xff01;**在企业环境中&#xff0c;出于安全和管理的考虑&#xff0c;很多公司会设置内网代理服务器&#xff0c;以控制和监管内部网络的访问。这就意味着&#xff0c;员工在使…

jsp多站点图书管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 多站点图书管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5…

git常用命令小记

&#xff08;文章正在持续更新中&#xff09; git init - 在当前目录下初始化一个新的 Git 仓库。 git clone [url] - 克隆远程仓库到本地。 git add [file] - 将文件添加到暂存区。 git commit -m "commit message" - 将添加到暂存区的文件提交到本地仓库。 git pus…

STM32 Nucleo-64 boards 外设资源引脚对应关系图

STM32 Nucleo-64 boards 外设资源引脚对应关系图 1. STM32 NUCLEO-F103RB1.1 串口对应关系图1.2 I2C对应关系图 【参考博文】 1. STM32 NUCLEO-F103RB 1.1 串口对应关系图 1.2 I2C对应关系图 注意&#xff1a;STM32 NUCLEO-F103RB 在Arduino 端子分配的 I2C 重映射为 PB8 PB9 …

Python词频统计(数据整理)

请编写程序&#xff0c;对一段英文文本&#xff0c;统计其中所有不同单词的个数&#xff0c;以及词频最大的前10%的单词。 输入格式: 输入给出一段非空文本&#xff0c;最后以符号#结尾。输入保证存在至少10个不同的单词。 输出格式: 在第一行中输出文本中所有不同单词的个数…

101. 对称二叉树

101. 对称二叉树 判断二叉树是否对称 check就完事儿了 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val…

macOS 13.6上Sublime无法使用Package Control问题

macOS 13.6上Sublime无法使用Package Control问题 最近升级系统重装Sublime后发现Package Control不能使用&#xff0c;在Settings -> Package Control下输入Install没有任何提示。 然后使用 CTRL 或者 View -> Show Console 查看日志&#xff0c;看到打印了一堆错误…

直击2023云栖大会-大模型时代到来:“计算,为了无法计算的价值”

2023年的云栖大会以“计算&#xff0c;为了无法计算的价值”为主题&#xff0c;强调了计算技术在现代社会中的重要性&#xff0c;特别是在大模型时代到来的背景下。 大模型时代指的是以深度学习为代表的人工智能技术的快速发展&#xff0c;这些技术需要大量的计算资源来训练和优…

深度学习设计基于Tensorflow卷积神经网络猫的品种识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Tensorflow卷积神经网络的猫的品种识别系统可以用于自动识别猫的品种类型。下面我将为您介绍一下这个系统的基本…

Python函数的基本使用(一)

Python函数的基本使用&#xff08;一&#xff09; 一、函数概述二、函数的定义2.1 函数的语法2.2 语法说明2.3 函数定义的方式2.4 总结 三、函数的调用3.1 函数调用语法3.2 语法说明3.3 函数调用 四、函数的参数4.1 参数的分类4.2 必需参数4.3 默认值参数4.4 关键字参数4.5 不定…

路由策略,gRPC 路由如何实现

目录 一、为啥我们要路由策略&#xff1a; 二、基于gRPC 路由策略 一、为啥我们要路由策略&#xff1a; 我们可以重新回到调用方发起 RPC 调用的流程。在 RPC 发起真实请求的时候&#xff0c;有一个步骤就是从服务提供方节点集合里面选择一个合适的节点&#xff08;就是我们…

保育员个人简历精选7篇

想要在保育员职位的求职过程中脱颖而出吗&#xff0c;参考这7篇精选的保育员简历案例&#xff01;无论您的经验如何&#xff0c;都能找到适合自己的简历样式及参考内容。 保育员个人简历模板下载&#xff08;可在线编辑制作&#xff09;&#xff1a;来幻主简历&#xff0c;做好…

第二十四章 控制到 XML 模式的映射

文章目录 第二十四章 控制到 XML 模式的映射查看支持xml的类的模式 第二十四章 控制到 XML 模式的映射 对于任何支持XML的类&#xff0c;都有一个用于该类的隐式XML模式&#xff0c;可以查看它。 IRIS 提供了修改该模式的方法。 本主题中的XML示例采用文字格式。 类和属性参…

JavaWeb | 验证码 、 文件的“上传”与“下载”

目录&#xff1a; 验证码 和 文件的“上传”与“下载”1.验证码1.1在JSP上开发验证码 2.“文件上传” 和 “文件下载”2.1“文件上传 ”2.2“文件下载” 验证码 和 文件的“上传”与“下载” 1.验证码 验证码&#xff1a;就是由服务器生成的一串随机数字或符号形成一幅图片&am…

在线地图叠加WMS服务,配合WFS数据服务实现图层叠加,属性查看功能

在线地图叠加WMS服务&#xff0c;配合WFS数据服务实现图层叠加&#xff0c;属性查看功能 实现思路实现方式备注&#xff1a;计算bbox参数值网上还提供了以下方式 实现思路 根据WFS服务参数可以看出&#xff0c;一种是空间查询&#xff08;一定范围内的数据查询&#xff09;、还…

微服务的流量管理-服务网格

对于单体应用来说&#xff0c;一般只有流入和流出两种流量。而微服务架构引入了跨进程的网络通信&#xff0c;流量发生在服务之间。由许多服务组成了复杂的网络拓扑结构&#xff0c;每次请求都会产生流量。 这些流量如果没有妥善的管理&#xff0c;整个应用的行为和状态将会不…

全局变量为什么没有野指针

全局变量为什么没有野指针&#xff1f; 全局变量是指在程序的任何地方都可以访问的变量&#xff0c;它们通常存储在静态内存区域&#xff0c;也称为数据段。野指针是指指向非法或不可用内存地址的指针&#xff0c;它们可能会导致内存泄漏、程序崩溃或数据损坏。 全局变量没有野…

封装Servlet使用自定义注解进行参数接收

文章目录 前言一、前后对比✨二、具体实现&#x1f387;三、效果展示&#x1f38f; 前言 先说项目背景&#xff0c;本项目是本人在校期间老师布置的作业&#xff08;就一个CRUD&#xff09;&#xff0c;课程是后端应用程序设计&#xff0c;其实就是servlet和jsp那一套&#xf…