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>
);
};