简单介绍下SVG格式图标在React项目中的使用
首先要下载svg格式图标,推荐使用 iconfont.cn,下载之后,直接当图片使用也可以,但是作为图片使用就不方便更改它的颜色,对于活动按钮和非活动按钮的区分不是很好。
作为svg文件使用之前,我们需要做一些准备工作:安装loader,配置webpack
安装: 需要安装svg-sprite-loader和svgo-loader,执行命令yarn add svg-sprite-loader svgo-loader -D。"svgo"的"o"意思是optimize, 优化的意思,比如有些svg文件自身就有fill属性,导致我们后期给他添加颜色失败,就可以通过svgo-loader来解决这个问题
webpack配置: 需要在webpack.config.js中配置,但是在项目中找不到,查看React官方文档,发现它默认是隐藏的,通过命令yarn eject调出配置文件,调出之后就不能再隐藏了
具体配置: webpack.config.js
{
test: /\.svg$/,
use: [
{loader: 'svg-sprite-loader', options: {}},
{
loader: 'svgo-loader', options: {
plugins: [
{removeAttrs: {attrs: 'fill'}} // 意思是移除fill属性
]
}
}
]
},
使用:
- TreeShaking:用import引入.svg需要使用一下,否则就会TreeShaking,被删掉,改用require,因为TreeShaking不适用于require
require('icons/money.svg');
require('icons/tag.svg');
require('icons/chart.svg');
- 使用svg图标,代码示例:xlink
<li>
<svg className={"icon"}>
<use xlinkHref="#money"/>
</svg>
<Link to="/tags">标签</Link>
</li>
- 发现每个svg都需要require引入一次,当svg多的时候,就会有很多重复的require,我们可以将其封装成一个组件,通过props传入不同的文件名,来显示不同的svg图标
- 这里使用到了classnames插件,方便动态的提供样式。安装方法为:
yarn add classnames@2.2.6; yarn add --dev @types/classnames@2.2.6
import React from 'react';
import cs from 'classnames'
let importAll = (requireContext: __WebpackModuleApi.RequireContext) =>
requireContext.keys().forEach(requireContext);
try {importAll(require.context('icons', true, /\.svg$/));}
catch (error) {console.log(error);}
type Props ={
name?: string;
} & React.SVGAttributes<SVGElement>
const Icon = (props: Props)=>{
const {name, children, className, ...rest} = props;
return (
<svg className={cs('icon', className)} {...rest}>
{props.name && <use xlinkHref={'#' + props.name} />}
</svg>
)
}
export default Icon;
说明:require.context是由webpack实现的
注意:因为没有安装webpack环境的TS依赖,上面的代码会报错,安装命令:yarn add --dev @types/webpack-env@1.15.1
- 封装为Icon组件后,就可以只用一个Icon标签来使用svg了
...
import Icon from './Icon';
...
<li>
<NavLink to="/tags" activeClassName="selected">
<Icon name="tag"/>
<span>标签</span>
</NavLink>
</li>
<li>
<NavLink to="/money" activeClassName="selected">
<Icon name="money"/>
<span>记账</span>
</NavLink>
</li>
<li>
<NavLink to="/statistics" activeClassName="selected">
<Icon name="chart"/>
<span>统计</span>
</NavLink>
</li>
...