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>
  );
};
相关推荐
Never_Satisfied6 小时前
在JavaScript / HTML中,让<audio>元素中的多个<source>标签连续播放
开发语言·javascript·html
Paddy哥6 小时前
html调起exe程序
前端·html
患得患失9496 小时前
【ThreeJs】【HTML载入】Three.js 中的 CSS2DRenderer 与 CSS3DRenderer 全面解析
javascript·html·css3
折翼的恶魔6 小时前
HTML基本标签二:
前端·html
Metaphor6926 小时前
Java 将 PDF 转换为 HTML:高效解决方案与实践
java·经验分享·pdf·html
mengyoufengyu8 小时前
Flask模板中使用Vue、ant-design-vue、@ant-design/icons-vue示例模板
vue.js·flask·html·ant-design-vue·antd-icons-vue
OEC小胖胖9 小时前
SEO 优化:元数据 (Metadata) API 和站点地图 (Sitemap) 生成
前端·javascript·前端框架·html·web·next.js
前端老鹰11 小时前
HTML `<meter>` 标签:原生度量衡指示器,直观展示百分比、评分等量化数据
前端·html
linux kernel12 小时前
第一部分:HTML
前端·html