关于前端:如何优雅的在微信小程序使用-SVG-字体图标

20次阅读

共计 5783 个字符,预计需要花费 15 分钟才能阅读完成。

本文思路来自理论我的项目的重构总结,欢送纠正和交换。如果对你有帮忙,还请点赞👍珍藏反对一下啦。

最近在重构一个我的项目,次要是做 H5 端和小程序端,这次打算开始多做总结啦,之前曾经总结一篇《如何优雅的治理 HTTP 申请和响应拦截器?》。

如果大家还有其余计划,欢送一起探讨哈~ 喜爱本文的敌人给个赞👍激励一下哈~

一、需要思考和方案设计

本文介绍的我的项目是应用 Taro 框架进行多端开发,目前次要适配 H5 端和微信小程序端。我的项目应用的字体图标库外部保护,目前托管在 iconfont 上。

1. 问题剖析

最近在重构的我的项目比拟古老(其实也就去年的),我的项目中应用到的图标早已更新 N 个迭代了,曾经由 单色图标 更新到 多色图标

很显著难看多了。

这里先依照 iconfont 的规定看看单色图标和多色图标应用上的区别:

单色图标的应用

单色图标应用起来比较简单(以 font-class 援用为例),只须要 2 个步骤:

  • 第一步:拷贝我的项目上面生成的 fontclass 代码:

    //at.alicdn.com/t/font_8d5l8fzk5b87iudi.css
  • 第二步:筛选相应图标并获取类名,利用于页面:

    <i class="iconfont icon-xxx"></i>

多色图标的应用

多色图标应用起来也很简略(以 symbol 援用为例),只须要 3 个步骤:

  • 第一步:拷贝我的项目上面生成的 symbol 代码:

    //at.alicdn.com/t/font_8d5l8fzk5b87iudi.js
  • 第二步:退出通用 css 代码(引入一次就行):

    <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 标签来实现。

于是我在小程序文档找了良久,也只看到了 <Image> 组件可能应用 SVG,介绍如下:

image 图片。反对 JPG、PNG、SVG、WEBP、GIF 等格局,2.3.0 起反对云文件 ID。

其属性 src 的值为图片资源地址,这就意味着,不能应用 SVG 字体图标了。因而咱们须要想想变通的方法。

(这里不探讨将 iconfont 上图标下载为图片来援用的状况)

2. 方案设计

既然咱们理解了单色图标和多色图标的应用形式:

  • 单色图标:任意标签(如 div 标签)+ 对应字体图标 class 名称
  • 多色图标:应用 svg 标签 + use 标签设置 xlink:href 属性

首先马上想到的是,能不能汇合两者应用形式,实现任意标签通过 class 名称来应用多色图标?

答案是能够的,只须要对图标文件进行格局转换,即 将多色字体图标转换为能通过 class 名称来援用的字体图标文件

那接下来只有看看如何实现格局转换即可。

二、重构后的成果

这边我以其中一个页面进行重构,最初将单色图标全都换成新的多色 SVG 字体图标,成果如下:

三、计划一:手动转换图标文件

目前我尝试了两套计划,并且都顺利实现成果,这边先分享一下这两种计划,而后再补充阐明我抉择哪个计划和起因:

该计划实现的是手动将字体图标库文件转换成能通过 class 名称来援用的图标库。
应用到的工具有:

  1. icomoon:https://icomoon.io/ 用来打包图标。
  2. transfonter:https://transfonter.org/ 用来生成 base64 格局的图标。

接下来开始试试:

步骤一:通过 iconfont 下载须要的 SVG 格局的图标

这边多下载了几个,都是 svg 格局的文件,如下图:

步骤二:打包字体图标

这一步是将零散个多个 SVG 多色图标打包成一个字体图标文件,这一步须要应用 https://icomoon.io/:

步骤三:字体图标进行 Base64 编码

接下来就须要将打好的字体图标进行 base64 压缩,这边应用 https://transfonter.org/ 来操作。

第一步抉择后面打好的包外面的 .ttf 文件:

设置参数,并导出文件:

步骤四:合并字体图标

通过后面几个步骤,咱们当初曾经有 2 个包:

  • 第一个包:icomoon 生成的包

  • 第二个包:transfonter 生成的包

接下来咱们开始将两个包合并:
将第一个包 style.css 文件除 @font-face 的内容复制到第二个包 stylesheet.css 文件前面。

这样就取得一份新的字体图标文件,其实也能够拷贝到一份新的 css 文件中。

应用字体图标

咱们将后面批改后的文件改名为 icon.scss 并引入到我的项目:

// app.scss

@import "./style/icon.scss";

代码中应用图标:

<View className="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>

最初成果如下:

踩坑记录

在应用计划一的时候,踩了好几个坑,这边挑两个来说:

  • 应用时,须要手动增加几个 <View classname="path*"></View> 元素

刚开始应用,图标始终没有进去,前面察看字体图标,它是在容器元素下很多个 path1path2 等元素的伪类中去渲染图标内容:

所以应用时须要手动增加一下。

  • 默认图标会是一个大的块级元素,导致图标显示有问题

这是因为手动加的 class 为 path* 的 View 标签自身是块级元素,所以这里只有简略加个 display: 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;

到这边,计划一实现实现。

四、计划二:借助第三方库实现

因为第一个计划应用起来比拟繁琐,于是我又再钻研其余简略点的计划。

直到我看到 taro-iconfont-cli 这个库。

在 Taro 框架中应用 iconfont 图标,不依赖字体,反对多色调。

目前反对平台包含:

  • 微信小程序
  • 支付宝小程序
  • 百度小程序
  • 头条小程序
  • QQ 小程序
  • H5

有以下个性:

  • 一键生成规范组件,多端反对
  • 使用方便,import 即可
  • 反对多色调
  • 反对自定义色彩
  • 反对 ES6 和 TypeScript 两种模式

依照文档形容,只须要 3 个步骤,那么试试看:

步骤一:装置 taro-iconfont-cli

# Yarn
yarn add taro-iconfont-cli --dev

# Npm
npm install taro-iconfont-cli --save-dev

须要留神的是,如果应用的是 Taro 2.x,请装置 **taro-iconfont-cli@2.1.0**,并浏览旧版的 README.md。

步骤二:生成配置文件

通过命令生成 iconfont.json 配置文件:

npx iconfont-init

# 可传入配置输入门路
# npx iconfont-init --output iconfont.json

此时我的项目根目录会生成一个 iconfont.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
}

symbol_url 值须要在 iconfont 中复制

步骤三:生成 Taro 规范组件

通过命令,生成 Taro 规范组件:

npx iconfont-taro

# 可传入配置文件门路
# npx iconfont-taro --config iconfont.json

通过控制台,咱们能够看到 taro-iconfont-cli 为每个图标独自生成一个 Taro 组件:

应用字体图标

依照文档应用办法,应用的时候,只须要引入 IconFont 组件,通过 name 名称来抉择对应图标即可:

// 省略其余代码

import IconFont from '@components/Iconfont/index';

<IconFont name="exe-knowledge-ppt"></IconFont>

依照文档提醒,还有更多应用办法:

// 原色调
<IconFont name="alipay" />

// 单色:红色
<IconFont name="alipay" color="red" />

// 多色:红色 + 橘色
<IconFont name="alipay" color={['red', 'orange']} size={300} />

// 不同格局的色彩写法
<IconFont name="alipay" color={['#333', 'rgb(50, 124, 39)']} />

// 与文字对齐
<View style={{display: 'flex', alignItems: 'center'}}>
  <Text>Hello</text>
  <IconFont name="alipay" />
</View>

踩坑记录

  1. 字体大小设置问题

因为通过这种形式导出的图标,是个独自组件,应用时如果须要设置图标大小,须要通过设置其 widthheight 属性进行设置。

通过 font-size属性无奈设置字体图标的大小。

五、计划比照和抉择

这次只尝试了这两种计划,都能顺利完成需要。如果大家有其余计划,欢送一起评论区探讨~

接下来 以生成上面雷同 20 个多色图标为规范,剖析这两种计划:

先看看比照后果:

手动转换图标文件 借助 taro-iconfont-cli 库实现
生成难易水平 简单 简略
应用难易水平 简略 简略
资源占用水平 27kb 420kb(我的项目未打包前)

剖析每个我的项目:

1. 比照生成难易水平

  • 「手动转换图标文件」须要每次将图标独自下载,再进行打包,当图标数量较多,其工作量就较大。
  • 「taro-iconfont-cli」只需设置字体图标库地址,主动下载并生成组件,较为不便。

2. 比照应用难易水平

两者应用起来都比较简单:

  • 「手动转换图标文件」为元素增加 class 名称即可。
  • 「taro-iconfont-cli」为元素增加 name 属性。

    3. 比照资源占用状况

    资源占用差别就很大了,剖析下起因:

  • 「手动转换图标文件」是将图标从新打包,最初生成的都是 base64 编码的内容,绝对较小。
  • 「taro-iconfont-cli」是为每个图标生成一个组件,独自一个文件,还有附加各个平台的文件,因而较大。

    4. 抉择计划

    思考到目前我的项目所应用的字体图标比拟少(20 个以内),后续开发人员上手难度问题,我最终应用「taro-iconfont-cli」这套计划。
    尽管这个计划生成的组件资源占用会稍大,然而目前应用图标较少,并且能够通过打包工具、CDN 等罕用优化形式进行优化。

六、本文总结

本文通过一次简略的我的项目重构,总结我的项目中小程序应用 SVG 多色图标的计划,目标是为了实现在小程序中可能失常应用 SVG 多色图标,并且也为内容越来越多独立站点的我的项目积攒教训,毕竟各个我的项目具备相关性。

最初,「taro-iconfont-cli」计划目前曾经在外部 npm 仓库保护,采纳版本控制,不便不同我的项目应用时缩小抵触。

当然,本文是基于我的经验总结,欢送大家有更好的计划,一起探讨学习~~

参考文章

  • 微信小程序中应用 svg 字体图标教程 ——图解三步,很清晰 
  • Taro-Iconfont 
正文完
 0