使用React创建SVG图标系统
Icon图标在Web应用或Web页面中起着至关重要的作用。它除了起到一定装饰作用之外,还可以在不添加任何文本信息的情况之下向用户传达正确的含义。在当今的Web开发中,有许多不同的方式将图标运用于Web应用或Web页面上。同样,在社区中也有很多介绍Icon图标系统构建的方法,比如早期的雪碧图,字体图标以及SVG Sprites等。但是今天我想从不同的角度来和大家聊聊,如何基于React框架下构建属于自己的SVG图标系统。感兴趣的同学,欢迎继续往下阅读。
特别声明:如果你是基于Vue框架开发,你可以移步阅读《如何在Vue项目中使用SVG Icon》一文,当然,文章中提到的相关技术同样也适应于Vue体系以及其他的开发体系。
为什么选择使用SVG Icons
早在几年前,我在《Web中的图标》一文中就和大家一起探讨过图标在Web开发中的几种使用方式以及他们之间的利弊。其实随着CSS的@font-face
特性的到来,使用字体图标比使用雪碧图更受欢迎。但最近几年,随着客户端对SVG的支持越来越友好,不管是设计师还是开发者越来越觉得SVG图标要比字体图标还要更友好。在社区中有关于这方面的讨论也比较多,比如 @Chris Coyier的《Inline SVG vs Icon Fonts》和@Mallik Cheripally的《Inline SVG or Icon Fonts: Which One to Use》文章就做过详细的对比。
就算是到今天为止,这样的话题也没有停止过。不过我自己觉得,使用SVG Icon有以下几点优势:
- 可读性:SVG可以直接内联使用,开发者可以在SVG代码中直接添加
title
以及ARIA相关的特性,这极大地提高了可访问性(A11Y),特别是在仅用图标向用户传递信息的情况下。相比之下,字体图标在这方面就处于劣势(当然可以借画其他手段来实现A11Y的能力) - 清晰度:众所周知,SVG是矢量图,它不会因为不同的分辨率造成不清晰;而字体图标在一些显示器上不那么清晰。虽然使用CSS的
font-smoothing
让字体图标避免这种情况,但是“不完全将字体平滑化”,font-smoothing
属性是很难覆盖到 - 加载失败:可能很多同学都越到过,使用字体图标的时候,Web页面渲染的时候,字体图标会以一个带有
x
符号的方框替代的情况,这主要是因为跨域(CORS
)问题或Opera mini
造成字体文件加载失败引起的,这也是使用字体图标很蛋疼的地方。而在SVG中是不会出现这个现象 - 扩展性:对于字体图标,如果希望给图标某部分改变样式或加载动效,那么是不可能实现的;但SVG图标可以轻易做到。这主要是因为SVG是
XML
标记语言,可以像操作DOM一样操作SVG的元素,这样一来,就可以晚于给SVG图标的某部分改变样式(比如填充颜色),甚至添加动效
当然,SVG还有其他的优势。这也是SVG Icon被运用于Web开发中的主要原因之一。另外,如果你在Web开发当中,经常会用到图标的话,那么我们构建一个图标系统就变得尤其重要;还有一点,如果你以前就有一个字体图标系统,希望将它们换成SVG图标系统,那么接下来的内容就对你非常有用。
SVG使用姿势
SVG(或者说SVG图标)运用于Web有很多种方式,不过众多方式中更推荐于内联方式,特别是SVG图标的使用场景。
在当下Web开发一般都是基于一些JavaScript框架进行开发,比如说React,Vue等。这些前端开发框架允许我们将UI抽出来,构建成一个可复用的UI组件。这也意味着,我们可以创建一个通用的图标组件,并使用type
属性来指定SVG图标,然后以内联方式呈现在Web页面中。比如:
<Icon type="book" />
如何是在React框架下还可以直接将SVG文件当React组件使用:
import { ReactComponent as ReactLogo } from './logo.svg';
<ReactLogo className="App-logo" />
当然,具体的使用有很多种方式,正如《SVG在React中的运用》和《如何在Vue项目中使用SVG Icon》中所介绍的,我们可以直接将.svg
文件转换成Web组件使用。
特另声明,只要你是基于类似于Webpack来构建的项目,有很多方式将SVG转换成Web组件(不同的加载器,使用方式略有细微的差异)。
接下来,我们以几种不同的方式来看看怎么一步一步构建属于自己的SVG图标系统。注意,下面的内容都是基于React体进行开发的。
SVG Sprites
在《SVG在React中的运用》中我们介绍的几种将SVG自动转换为React组件的使用方式,虽然方式不同,但最终呈现在Web中的效果是一样的。文章中提到的几种方式都有着一个共性:
SVG内联到HTML!
他们有着一个最大的优势:直接将SVG文件转换为React组件,但也有着一个最明显的缺点,比如说,我在同一个页面不同的地方使用了同一个SVG图标组件,这个时候会有相同的代码插入到DOM中:
import {ReactComponent as Home} from 'home.svg'
const App = () => (
<>
<header>
<Home />
</header>
<!-- ... -->
<footer>
<Home />
</footer>
</>
)
export default App
这个时候,渲染出来的Web页面,你会发现在<header>
和<footer>
引入了两段相同的SVG代码,类似像下面这样:
<div id="root">
<header>
<svg t="1598444628462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1160" width="200" height="200">
<path d="M950.153231 461.510311l-122.16073-111.794026-1.27984-1.087864 0-136.87889c0-10.110736-8.190976-18.365704-18.365704-18.365704l-82.549681 0c-10.110736 0-18.365704 8.190976-18.365704 18.365704l0 35.835521-5.11936-4.351456-150.829146-134.255218c-0.63992-0.575928-1.343832-1.023872-1.983752-1.471816-11.070616-8.766904-24.060992-13.43832-37.563305-13.43832-14.07824 0-27.51656 4.991376-38.971129 14.526184-0.127984 0.191976-0.31996 0.383952-0.511936 0.447944l-398.670166 352.595926c-10.55868 9.086864-12.926384 26.428696-5.247344 38.907137 7.67904 12.414448 22.525184 15.230096 33.083865 6.207224l398.350206-352.40395c0.063992 0 0.191976-0.127984 0.255968-0.191976C503.68104 151.149106 507.712536 149.613298 512 149.613298s8.31896 1.535808 11.710536 4.415448c0.191976 0.127984 0.383952 0.255968 0.575928 0.383952l398.094238 352.211974c10.55868 9.022872 25.404824 6.271216 33.083865-6.207224C963.079615 487.939008 960.775903 470.597175 950.153231 461.510311z" p-id="1161" />
<path d="M543.868016 271.1981c0-0.063992-0.127984-0.127984-0.191976-0.191976-9.342832-7.807024-20.349456-11.966504-31.740032-12.030496-11.390576 0-22.333208 4.15948-31.67604 11.902512-0.063992 0.127984-0.191976 0.191976-0.31996 0.31996l-276.189476 247.969004c-6.207224 5.311336-9.790776 13.694288-9.790776 22.525184l0.191976 328.598925c0 32.955881 26.748656 59.704537 59.704537 59.704537l156.780402 0 0-204.198475c0-41.338833 28.412448-74.742657 63.480065-74.742657l65.911761 0c35.067617 0 63.544057 33.403825 63.544057 74.742657l0 204.198475 166.315211 0c32.955881 0 59.704537-26.748656 59.704537-59.704537l0.255968-328.598925c0-8.830896-3.647544-17.213848-9.790776-22.525184L543.868016 271.1981z" p-id="1162" />
</svg>
</header>
<!-- ... -->
<footer>
<svg t="1598444628462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1160" width="200" height="200">
<path d="M950.153231 461.510311l-122.16073-111.794026-1.27984-1.087864 0-136.87889c0-10.110736-8.190976-18.365704-18.365704-18.365704l-82.549681 0c-10.110736 0-18.365704 8.190976-18.365704 18.365704l0 35.835521-5.11936-4.351456-150.829146-134.255218c-0.63992-0.575928-1.343832-1.023872-1.983752-1.471816-11.070616-8.766904-24.060992-13.43832-37.563305-13.43832-14.07824 0-27.51656 4.991376-38.971129 14.526184-0.127984 0.191976-0.31996 0.383952-0.511936 0.447944l-398.670166 352.595926c-10.55868 9.086864-12.926384 26.428696-5.247344 38.907137 7.67904 12.414448 22.525184 15.230096 33.083865 6.207224l398.350206-352.40395c0.063992 0 0.191976-0.127984 0.255968-0.191976C503.68104 151.149106 507.712536 149.613298 512 149.613298s8.31896 1.535808 11.710536 4.415448c0.191976 0.127984 0.383952 0.255968 0.575928 0.383952l398.094238 352.211974c10.55868 9.022872 25.404824 6.271216 33.083865-6.207224C963.079615 487.939008 960.775903 470.597175 950.153231 461.510311z" p-id="1161" />
<path d="M543.868016 271.1981c0-0.063992-0.127984-0.127984-0.191976-0.191976-9.342832-7.807024-20.349456-11.966504-31.740032-12.030496-11.390576 0-22.333208 4.15948-31.67604 11.902512-0.063992 0.127984-0.191976 0.191976-0.31996 0.31996l-276.189476 247.969004c-6.207224 5.311336-9.790776 13.694288-9.790776 22.525184l0.191976 328.598925c0 32.955881 26.748656 59.704537 59.704537 59.704537l156.780402 0 0-204.198475c0-41.338833 28.412448-74.742657 63.480065-74.742657l65.911761 0c35.067617 0 63.544057 33.403825 63.544057 74.742657l0 204.198475 166.315211 0c32.955881 0 59.704537-26.748656 59.704537-59.704537l0.255968-328.598925c0-8.830896-3.647544-17.213848-9.790776-22.525184L543.868016 271.1981z" p-id="1162" />
</svg>
</footer>
</div>
这对于有代码洁癖的同学来说,可能无法接受。
如果你对SVG的基础有点了解话,你可能会想到SVG的<symbol>
和<use>
元素。比如下面这个简单示例:
<svg style="display:none;">
<!-- Twitter Icon -->
<symbol id="twitter" viewBox="0 0 32 32">
<path d="M32 6.076c-1.177 …" fill="#000000"></path>
</symbol>
<!-- Facebook Icon -->
<symbol id="facebook" viewBox="0 0 32 32">
<path d="M32 6.076c-1.177 …" fill="#000000"></path>
</symbol>
<!-- 其他Icon图标 -->
</svg>
然后在需要使用图标的地方用<use>
标签来引用对应<symbole>
中的id
名:
<svg class="twitter__icon">
<use xlink:href="#twitter"></use>
<svg>
我复制了@Adam Moore在CodePen的示例,向大家展示SVG的<symbole>
和<use>
的具体使用和对应效果:
如果你使用浏览器查看代码的话,会像下图这样:
而这种方法也被称为是SVG Sprites。社区中有关于这方面的讨论也非常的多:
- An Overview of SVG Sprite Creation Techniques
- Building Icon Systems With SVG
- Accessible SVG Icons with Inline Sprites
- SVG Sprite
- 如何实现跨浏览器的SVG Sprites
- 使用SVG symbols建立图标系统
其实在《如何在Vue项目中使用SVG Icon》一文中也介绍了这种方法来构建SVG Sprites,不过这里想和大家接着聊在React中如何基于Webpack的加载器(比如svg-sprite-loader
)构建SVG Sprites图标系统。
特别声明:下面的示例是基于Create React App构建的React项目,并且通过
npm run eject
命令开启了Webpack的自定义配置!
规划项目目录和准备SVG图标
首先需要有一个地方(文件目录)来放置SVG图标。所以我在src/
目录下创建了一个新目录assets/
,并且在assets
目录下创建了icons/
目录,主要用来放置SVG图标。为了节约时间,我直接在iconfont.cn平台上下载了一些SVG图标:
生成SVG Sprite:svg-sprite-loader
前面向大家演示了,在SVG中如何使用<defs>
和<symbol>
标签来构建SVG Sprites的表(每个<symbol>
对应的是一个SVG图标)。但是在React框架开发体系下,我们可以借助Webpack的工程配置能力和 svg-sprite-loader
可以根据自动引入的SVG图标生成对应的SVG Sprites表。
假设你已具备了一个React的开发体系(基于Webpack),那么可以在项目中安装svg-sprite-loader
:
» npm i --save-dev svg-sprite-loader
并且在webpack.config.js
中添加有关于svg-sprite-loader
相关的配置:
module: {
rules: [
{
oneOf: [
{
test: /\.svg$/,
loader: require.resolve('svg-sprite-loader'),
options: {
symbolId: 'icon-[name]'
}
},
]
}
]
}
在此基础上,我们需要一个模板文件。比如在src/assets/icons
目目中创建一个index.js
文件:
const requireAll = requireContext => requireContext.keys().map(requireContext);
const req = require['context']('./', false, /\.svg$/);
requireAll(req);
可以在项目的index.tsx
中引入这个模板文件:
// index.tsx
import './assets/icons/index.js'
引入了index.js
文件之后,那么/src/components/icons
目录下的所有.svg
文件就会合并成一个SVG Sprites,并且插入到index.html
中:
当然,仅有这个还不行,我们还需要一个React组件。比如在/src/components/
创建一个SvgIcon
组件:
import React from 'react'
interface ISvgIconProps {
type: string;
className?: string;
}
const SvgIcon = (props: ISvgIconProps) => {
const {type, ...rest} = props
return <svg
width="1em"
height="1em"
fill="currentColor"
className={className}
{...rest}
xmlns="http://www.w3.org/2000/svg"
dangerouslySetInnerHTML={{
__html: `<use xlink:href="#icon-${type}" href="#icon-${type}"></use>`,
}}>
</svg>
}
export default SvgIcon;
这样一来,调用SvgIcon
组件时,只需要将其type
属值的值设置为/src/assets/icons/
下的.svg
文件名称,就可以将.svg
文件渲染到页面上:
// App.tsx
import React from 'react';
import SvgIcon from './components/SvgIcon'
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<SvgIcon type="facebook" />
<SvgIcon type="github" />
</header>
</div>
);
}
export default App;
其实你会发现,目前这个效果并不太好。即使我们在SvgIcon
组件中显式的设置了fill="currentColor"
,但Icon颜色并没有根据当前组件color
颜色来改变SVG图标颜色。这就要是在/src/assets/icons
目录下的.svg
源文件中的SVG元素上有显式设置fill
的值:
// src/assets/icons/alipay.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1598491090685" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5634" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<defs>
<style type="text/css"></style>
</defs>
<path d="M578.656 651.648S512 704.96 487.776 718.944a300.512 300.512 0 0 1-59.104 26.08 247.808 247.808 0 0 1-46.88 10.688c-13.408 1.472-24.512 2.4-33.312 2.848a7.232 7.232 0 0 1-3.136 0.64h-10.08a249.92 249.92 0 0 1-65.088-8.224 164.768 164.768 0 0 1-53.12-24.192 117.856 117.856 0 0 1-35.84-40.256c-8.832-16.16-13.216-34.912-13.216-56.288 0.416-18.432 5.44-35.2 15.04-50.304a133.504 133.504 0 0 1 37.44-38.4 177.536 177.536 0 0 1 50.976-23.904 172.384 172.384 0 0 1 56.288-6.88c18.432 0.832 36.256 3.008 53.44 6.56a485.44 485.44 0 0 1 49.376 12.928c15.712 5.024 30.592 10.464 44.64 16.32 14.08 5.92 27.36 11.552 39.936 17.024a615.04 615.04 0 0 0 32.704 12.576c12.16-15.52 22.4-30.72 30.816-45.6a473.504 473.504 0 0 0 33.344-72c2.944-8.384 4.8-14.24 5.664-17.6h-272.96v-30.208H473.6v-69.76H294.368v-30.208h179.264v-56.64c0-3.744 2.08-6.784 6.272-9.088 4.192-2.304 9.024-3.872 14.464-4.736 6.304-1.248 13.44-1.888 21.376-1.888h48.416v72.32h184.288v30.208H564.16v69.792h146.432l0.096-0.64v0.64h-0.096c-2.944 18.688-7.936 38.4-14.976 59.136a455.52 455.52 0 0 1-26.112 61.632 432.96 432.96 0 0 1-45.6 71.04s144.32 69.088 296.704 93.376C945.888 639.84 960 577.536 960 512c0-247.424-200.576-448-448-448S64 264.576 64 512c0 247.392 200.576 448 448 448 153.472 0 288.896-77.184 369.664-194.848-82.048-17.888-169.216-54.08-303.04-113.504zM224 621.12c-1.696 76.704 85.632 82.4 99.104 82.816 44.544 1.344 80.48-15.36 108.48-31.872 27.968-16.512 73.632-59.2 75.36-60.64 1.664-1.472 3.36-3.04 5.024-4.704-12.224-6.72-24.224-12.864-36-18.528-11.776-5.632-71.68-37.6-124.8-43.04C250.496 534.784 224.512 597.824 224 621.12z" fill="#181818" p-id="5635"></path>
</svg>
如果要达到fill="currentColor"
让SVG图标颜色能根据color
颜色设置,需要将<path>
中的fill
的值去掉,或者也显式设置为fill="currentColor"
。换句话说,如果你用到的SVG图标多的话,人肉操作也是很大的工作量,这个时候我们可以通过svgo-loader
来帮我们处理,而且它还能帮助我们对SVG源码做优化。
使用svgo-loader
需要先安装svgo
和svgo-loader
:
» npm install svgo svgo-loader --save-dev
同时在项目根目录下创建svgo
相关的配置文件,比如svgo-config.json
:
{
"plugins": [
{ "cleanupAttrs": true },
{ "cleanupEnableBackground": true },
{ "cleanupIDs": true },
{ "cleanupListOfValues": true },
{ "cleanupNumericValues": true },
{ "collapseGroups": true },
{ "convertColors": true },
{ "convertPathData": true },
{ "convertShapeToPath": true },
{ "convertStyleToAttrs": true },
{ "convertTransform": true },
{ "mergePaths": true },
{ "removeComments": true },
{ "removeDesc": true },
{ "removeDimensions": true },
{ "removeDoctype": true },
{ "removeEditorsNSData": true },
{ "removeEmptyAttrs": true },
{ "removeEmptyContainers": true },
{ "removeEmptyText": true },
{ "removeHiddenElems": true },
{ "removeMetadata": true },
{ "removeNonInheritableGroupAttrs": true },
{ "removeRasterImages": true },
{ "removeTitle": true },
{ "removeUnknownsAndDefaults": true },
{ "removeUselessDefs": true },
{ "removeUnusedNS": true },
{ "removeUselessStrokeAndFill": true },
{
"removeAttrs": { "attrs": "fill"}
},
{ "removeXMLProcInst": true },
{ "removeStyleElement": true },
{ "removeUnknownsAndDefaults": true},
{ "sortAttrs": true }
]
}
最后别忘了修改webpack.config.js
的配置:
const svgoConfig = require('../svgo-config.json');
module: {
rules: [
{
oneOf: [
{
test: /\.svg$/,
use: [
{
loader: require.resolve('svg-sprite-loader'),
options: {
symbolId: 'icon-[name]'
}
},
{
loader: 'svgo-loader',
options: svgoConfig,
}
]
},
]
}
]
}
重新执行npm run start
之后,你将看到的效果如下:
在此基础上,我们还可以通过CSS来调整SVG 图标大小:
<SvgIcon type="facebook" className="icon__facebook"/>
<SvgIcon type="github" className="icon__github" />
// app.css
.icon__facebook {
font-size: 10vw;
}
.icon__github {
font-size: 20vw;
color: #f36;
}
这个时候你看以的效果会像下图这样:
其实基于svg-sprite-loader
还可以用更简单地方式来构建SVG Sprites。接下来我们就来看svg-sprite-loader
的另一种使用方式。我们首先在src/
目录下构建一个Icon.js
的文件,然后输入下面代码:
// src/Icon.js
import React from 'react';
const files = require.context('!svg-sprite-loader!./assets/icons', false, /.*\.svg$/);
files.keys().forEach(files);
const Icon = (props) => {
const { type, className = '', ...rest } = props
return <svg
className={`icon icon__${className}`}
width="1em"
height="1em"
fill="currentColor"
{...rest}
>
<use xlinkHref={`#${type}`}></use>
</svg>
};
export default Icon;
有了这个Icon模板,我们就可以将其当作Icon
组件,并且在使用SVG图标的地方引入该组件,比如:
// App.tsx
import React from 'react';
import './App.css';
import Icon from './Icon'
function App() {
return (
<div className="App">
<header className="App-header">
<Icon type="facebook" />
<Icon type="wechat" />
</header>
</div>
);
}
export default App;
这个时候,你在浏览器中看到的效果如下:
从效果上来看,同样遇到前面碰到的现象,那就是fill="currentColor"
并没有起到什么效果,其中原因是一样的。我们可以使用SVGO工具帮助我们快速处理和优化SVG代码。而且还可以使用CSS来给SVG图标设置样式,比如图标的颜色、大小等:
.icon__facebook {
font-size: 20vw;
color: #f90;
}
.icon__wechat {
font-size: 30vw;
color: #f36;
}
这个时候Icon变成下图这样了:
SVGR构建SVG图标系统
我们在《SVG在React中的运用》一文中提到过SVGR可以自动将.svg
文件转换为React组件。这里要提到的是,我们还可以使用SVGR的高级模板来构建SVG图标系统。如果你对这方面感兴趣的话,可以阅读@winkerVSbecks的《React Icon System》一文。
基于Node服务构建SVG图标系统
@steveschoger使用Node相关服务构建了一个SVG图标系统,即 Heroicons。该系统提供了两百多个SVG图标,可以直接将.svg
文件转换成JSX(也可以理解成React组件):
Heroicons对应的源码可以在GitHub上获取。
在Github仓库中提供了React和Vue两个版本。我们也可以按照这种方式来借助Node服务来构建SVG图标系统。
Font Awesome 图标系统
Font Awesome 是社区中非常优势的图标库,而且是最有名的字体图标库,即 大家使用的时候,更喜欢使用字体图标的方式来使用Font Awesome!
如果你是基于React框架来开发项目的话,希望在项目中使用Font Awesome的话,除了以往的方式(引入字体),还可以React组件,即 React版本Font Awesome。该版本是由Font Awesome团队创建的一个React组件。不过它包括了免费 和 专业等多个版本。除此之外,它还有Regular(普通)、Light(线性)和 Solid(加粗)等版本。大家使用的时候,可以根据自己需要的版本安装对应的包:
// Font Awesome的基础包
» npm i -S @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/react-fontawesome
// Regular Icons
// 免费版本
» npm i -S @fortawesome/free-regular-svg-icons
// 专业版本
» npm i -S @fortawesome/pro-regular-svg-icons
// Light Icons
» npm i -S @fortawesome/pro-light-svg-icons
// Solid Icons
» npm i -S @fortawesome/free-solid-svg-icons
» npm i -S @fortawesome/pro-solid-svg-icons
// Duotone icons
» npm i -S @fortawesome/pro-duotone-svg-icons
// Brand icons
» npm i -S @fortawesome/free-brands-svg-icons
在需要使用的地方,引入相应的图标组件即可:
// App.tsx
import React from 'react';
import './App.css';
import { faHome, faAppleAlt } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
function App() {
return (
<div className="App">
<header className="App-header">
<FontAwesomeIcon icon={faHome} />
<FontAwesomeIcon icon={faAppleAlt} />
</header>
</div>
);
}
export default App;
渲染出来的结果如下图所示:
使用<FontAwesomeIcon />
组件也是将内联SVG代码的方式:
其中传给<FontAwesomeIcon />
的icon
的值对应的就是图标的类名,比如<i class="fas fa-apple-alt"></i>
中fa-apple-alt
换成faAppleAlt
:
<FontAwesomeIcon icon={faHome} />
另外,基于这个组件还可以扩展自己的图标,有关于这方面更详细的介绍可以阅读@Chris on Code的《How To Use Font Awesome 5 with React》一文。
小结
结合《SVG在React中的运用》一文,和大家一起探讨了在React中怎么使用SVG图标。换句话说,在React开好体系下,除了可以使用React自带的方式之外,还可以使用react-svg-loader
、SVGR将.svg
文件自动转换成React组件,还可以使用svg-sprite-loader
构建SVG Sprites,使用Node服务构建自己的图标系统,而且还可以使用React版本的Font Awesome,并且基于该体系扩展自己的SVG图标。
虽然方法都可以很好的帮助我们构建SVG图标系统,但我们在实际使用SVG图标的时候,希望能对SVG图标中的某些部分做一些调整,比如说更改某个路径的颜色,甚至是添加动效等。如果需要满足这些要求的话,前面提到这些方案都有一定的缺陷,也就是说,我们要在React体系中使用自定义或个性化SVG图标(或组件)就需要换过一种模式。有关于这方面的介绍,将在下一篇文章中和大家一起探讨。如果你对这方面感兴趣的话,欢迎持续关注后续的相关更新。如果你在这方面有更多经验或建议,欢迎在下面的评论中与我们共享。