svg图标在react项目中的使用

svg简介

svg(Scalable Vector Graphics,SVG)是一种可缩放的矢量图形,不会因放大缩小而损耗图片的清晰度,也可以通过css改变其样式。在项目开发中,一般在涉及简单的图标时会使用svg图。

svg的使用

先介绍几个标签,更详细的内容可以查看MDN文档。

<svg>是svg的容器元素,可以用于在当前文档(比如说,一个 HTML 文档)内嵌套一个独立的 svg 片段,渲染一个独立的svg图形。

<path>用来定义形状的通用元素。所有的基本形状都可以用 path 元素来创建。

html 复制代码
<body>
    <!-- 该片段展示的是一个心形图形 -->
    <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
      <path
        d="M 10,30
               A 20,20 0,0,1 50,30
               A 20,20 0,0,1 90,30
               Q 90,60 50,90
               Q 10,60 10,30 z" />
    </svg>
</body>

<symbol>用来定义一个图形模板对象,它可以用一个<use>元素实例化。symbol元素对图形的作用是在同一文档中多次使用,添加结构和语义。一个symbol元素本身是不呈现的。只有symbol元素的实例(亦即,一个引用了symbol<use>元素)才能呈现。

<use>从 SVG 文档中获取节点,并将它们复制到其他地方。使用href属性引用symbol元素中定义的模板对象(href的值匹配symbol中的id属性的值),渲染图形到当前<use>所在位置。

完整使用示例如下:

html 复制代码
<body>
    <!-- 在需要的地方引用,可以多次引用,可以使用style修改svg图形的样式 -->
  <svg style="width: 20px; height: 20px; fill: red;">
    <use href="#icon-home"></use>
  </svg>
  <svg style="width: 20px; height: 20px; fill: yellow;">
    <use href="#icon-home"></use>
  </svg>

      <!-- 隐藏在页面某处的 SVG 雪碧图 -->
  <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
    <!-- 每个图标定义为独立的 <symbol> -->
    <symbol id="icon-home" viewBox="0 0 24 24">
      <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
    </symbol>
    
    <symbol id="icon-user" viewBox="0 0 24 24">
      <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
    </symbol>
  </svg>
</body>

在react项目中使用

svg图标来源:

  • 设计软件导出:Figma、Sketch等
  • 手动编写:开发者直接编写svg代码
  • 图标库:从开源图标库中导出,如阿里巴巴矢量图标库iconfont。

将svg图标文件集中放在某个目录下,如:

arduino 复制代码
src/assets/icons/svg
├── home.svg
├── user.svg

如果是使用的vite构建工具,则需要下载vite-plugin-svg-icons包,会将所有的svg文件打包成雪碧图,即一个包含所有svg的<symbol>元素的代码,插入到HTML代码中。在界面,就可以使用<use>标签引用这些svg图片。

css 复制代码
npm install vite-plugin-svg-icons --save-dev

在vite.config.ts配置文件中将vite-plugin-svg-icons配置到plugins中:

javascript 复制代码
// ...
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
    // 将 SVG 文件打包成雪碧图
    createSvgIconsPlugin({
      iconDirs: [path.resolve(__dirname, 'src/assets/icons/svg')], // SVG 存放目录
      symbolId: 'icon-[name]', // 生成 symbol 的 ID 格式
    }),
  ],
  
  // 其他配置
  // ...
})

vite-plugin-svg-icons插件会在代码构建时,根据配置中的svg存放目录遍历所有svg文件,生成如下所示代码片段,并插入到html代码里。

xml 复制代码
  <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
    <symbol id="icon-home">...</symbol>
    <symbol id="icon-user">...</symbol>
    <!-- ... -->
  </svg>

上图是vite开发环境下的截图,会在DOM元素加载后自动将生成的svg代码注入到html中。

接下来就可以使用svg图标。

首先,编写SvgIcon组件,方便使用:

ts 复制代码
import type React from 'react';

interface SvgIconProps {
  name: string;
  className?: string;
}

const SvgIcon: React.FC<SvgIconProps> = ({ name, className = '', ...props }) => {
  return (
    // fill: currentColor; /* 继承父元素颜色 */
    <svg className={`w-[1em] h-[1em] fill-current ${className}`} aria-hidden='true' {...props}>
      <use href={`#icon-${name}`} />
    </svg>
  );
};

export default SvgIcon;

在react项目中任意地方使用:

ini 复制代码
const App = () => {
  return (
    <div>
      <SvgIcon name='home' className='text-blue-500' />
      <SvgIcon name='user' className='text-red-500' />
    </div>
  );
};
相关推荐
小小测试开发1 小时前
JMeter XPath提取器用法详解:XML/HTML响应数据提取神器
xml·jmeter·html
初学小白...1 小时前
HTML知识点
前端·javascript·html
Eiceblue11 小时前
通过 C# 将 HTML 转换为 RTF 富文本格式
开发语言·c#·html
_OP_CHEN14 小时前
前端开发实战深度解析:(一)认识前端和 HTML 与开发环境的搭建
前端·vscode·html·web开发·前端开发
喂自己代言14 小时前
HTML ``元素:链接外部资源的关键角色与用法
css·html
H_ZMY16 小时前
微信小程序 mp-html:专为小程序设计的富文本渲染组件
微信小程序·小程序·html
Hilaku19 小时前
这 5 个冷门的 HTML 标签,能让你少写 100 行 JS
前端·javascript·html
samroom20 小时前
什么是MVVM以及HTML小案例
前端·html
百***812721 小时前
【HTML+CSS】使用HTML与后端技术连接数据库
css·数据库·html
xiaoxue..1 天前
深入理解浏览器渲染流程:从HTML/CSS/JS到像素呈现
前端·javascript·css·html