本文思路来源于实际项目的重构总结,欢迎大家指正交流,如果对你有帮助的话请点赞收藏支持一下。
我目前正在重构一个项目,主要针对H5端和小程序端,这次打算开始多做一些总结,之前已经总结了一篇。
如果你还有其他的解决方案,欢迎一起讨论,如果喜欢这篇文章,就点个赞鼓励一下吧。
1. 需求考量与解决方案设计
本文介绍的项目采用Taro框架进行多终端开发,目前主要适配H5端和微信小程序端。项目使用的字体图标库为内部维护,目前托管于。
1.问题分析
最近在重构的项目比较老了(其实已经是去年的了),项目用到的图标已经更新了N次迭代,从“单色图标”变成了“多色图标”!
显然它好看多了。
这里我们先按照规则来看看单色图标和多色图标的区别:
使用单色图标
单色图标使用起来很简单(以 font- 为例),只需要 2 个步骤:
//at.alicdn.com/t/font_8d5l8fzk5b87iudi.css
<i class="iconfont icon-xxx">i>
使用多色图标
多色图标也很容易使用(以引言为例),只需 3 个步骤:
//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js
<style type="text/css">
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
style>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-xxx">use>
svg>
这两个图标使用起来非常方便,那么你是否好奇我写这篇文章的目的呢?
原因是“微信小程序不支持SVG字体图标!多色图标需要使用SVG标签。”
于是在小程序文档里找了很久,只看到该组件可以使用SVG,如下所述:
图片。支持JPG、PNG、SVG、WEBP、GIF等格式,从2.3.0开始支持云文件ID。
它的属性src的值为图片资源地址,也就是说无法使用SVG字体图标,因此,我们需要想办法解决。
(此处不讨论下载上述图标作为图片参考的情况)
2. 解决方案设计
现在我们了解了如何使用单色和多色图标:
首先想到的是,是否可以将这两种方法结合起来,并按名称为任何标签实现多色图标?
答案是可以的,你只需要转换一下图标文件的格式就可以了,也就是“将多色字体图标转换成可以通过名称引用的字体图标文件”。
那我们先来看看如何实现格式的转换。
2. 改造后效果
这里我重构了其中一个页面,最终将所有单色图标替换为新的多色 SVG 字体图标。效果如下:
3. 解决方案 1:手动转换图标文件
到目前为止,我已经尝试了两种解决方案,并且都效果很好。我将首先分享这两种解决方案,然后解释我选择了哪一种以及原因:
此解决方案是手动将字体图标库文件转化为可以通过名称引用的图标库,所用到的工具有:
: 用于封装图标。
:用于生成格式的图标。
让我们尝试一下:
步骤 1:下载所需的 SVG 图标
我这里又下载了几个文件,都是svg格式的,如下图:
第 2 步:包装字体图标
这一步是将分散的SVG多色图标打包成字体图标文件。此步骤需要:
步骤 3:对字体图标进行编码
接下来需要对输入的字体图标进行压缩,这可以在这里完成。
第一步,选择之前打包好的包中的.ttf文件:
设置参数并导出文件:

步骤 4:合并字体图标
经过上述步骤,我们现在有 2 个包:
接下来我们开始合并两个包:将第一个包的.css 文件除了@font-face之外的内容复制到第二个包的.css 文件的末尾。
这样你就会得到一个新的字体图标文件,其实也可以复制到一个新的css文件中。
使用字体图标
我们将之前修改的文件重命名为icon.scss并导入到项目中:
// app.scss
@import "./style/icon.scss";
代码中使用的图标:
"icon-exe-knowledge-ppt">
<View className='path1'>View>
<View className='path2'>View>
<View className='path3'>View>
<View className='path4'>View>
<View className='path5'>View>
<View className='path6'>View>
</View>
最终效果如下:
陷阱记录
使用解决方案 1 时,我遇到了几个陷阱。以下是其中两个:
刚开始使用的时候,图标并没有出现,后来观察字体图标,发现它在容器元素下的 、 等多个元素的伪类中被渲染了:
所以使用时需要手动添加。
这是因为手动添加的path*这样的View标签本身就是块级元素,所以这里只需要简单添加:flex即可。
并且其字体大小也可以通过font-size来设置:
display: flex;
font-size: 100px;
提取组件
考虑到可重用性,我将它们提取到 exe-svg-icon 组件中:
import Taro from '@tarojs/taro';
import { View, Text } from '@tarojs/components';
import classNames from 'classnames';
function EXESvgIcon(params) {
const { icon = 'exe-none' } = params;
const containerStyle = {
display: 'inline-block'
}
return (
<View className={classNames('svg', icon)} style={containerStyle}>
<View className='path1' style={containerStyle}>View>
<View className='path2' style={containerStyle}>View>
<View className='path3' style={containerStyle}>View>
{/* 一般图标 3 层,这边多预留几层,防止不够用 */}
<View className='path4' style={containerStyle}>View>
<View className='path5' style={containerStyle}>View>
<View className='path6' style={containerStyle}>View>
<View className='path7' style={containerStyle}>View>
<View className='path8' style={containerStyle}>View>
<View className='path9' style={containerStyle}>View>
View>
)
}
export default EXESvgIcon;
至此,方案1已经实施。
4.解决方案2:借助第三方库实现
由于第一个解决方案使用起来很麻烦,因此我研究了其他更简单的解决方案。
直到看到了taro--cli库。
使用Taro框架中的图标,不依赖字体,并支持多种颜色。
目前支持的平台包括:
它具有以下特点:
根据文档描述,只需要3步,尝试一下:
步骤一:安装 taro--cli
# Yarn
yarn add taro-iconfont-cli --dev
# Npm
npm install taro-iconfont-cli --save-dev
请注意,如果您正在使用 Taro 2.x,请安装“taro--cli@2.1.0”并阅读旧版本的 .md。
第 2 步:生成配置文件
通过命令生成.json配置文件:
npx iconfont-init
# 可传入配置输出路径
# npx iconfont-init --output iconfont.json
此时会在项目根目录下生成一个.json文件,内容如下:
{
"symbol_url": "请参考README.md,复制 http://iconfont.cn 官网提供的JS链接",
"save_dir": "./src/components/iconfont",
"use_typescript": false,
"platforms": "*",
"use_rpx": true,
"trim_icon_prefix": "icon",
"default_icon_size": 18,
"design_width": 750
}
该值需要复制到
步骤3:生成Taro标准组件
通过命令生成Taro标准组件:
npx iconfont-taro
# 可传入配置文件路径
# npx iconfont-taro --config iconfont.json
通过控制台我们可以看到,taro--cli 为每个图标生成了一个单独的 Taro 组件:
使用字体图标
按照文档中的使用说明,使用时只需要导入该组件,通过名称选择对应的图标即可:
// 省略其他代码
import IconFont from '@components/Iconfont/index';
<IconFont name="exe-knowledge-ppt">IconFont>