高清图标来袭!在vue项目中使用iconfont

为什么不切图标了

以前的图标我们非常喜欢用ps等工具切成一张张xxx.png图片,如果稍微懂点移动端适配,对dpr(设备像素比)有所了解的,还会切出类似[email protected],[email protected],[email protected]这样的图标,其中@1x表示用来适配dpr为1的手机,图像分辨率最低;@2x表示用来适配dpr为2的手机,图像分辨率稍高一些;@3x用来适配dpr为3的手机,图像分辨率最高。

最后,借助媒体查询如@media(min-device-pixel-ratio: 2){ }这样的代码对不同dpr的手机写上对应分辨率的图片,在大型项目中,本地静态图片可能类似这样:

高清图标来袭!在vue项目中使用iconfont_第1张图片

这是非常混乱且难以管理的。

而且,png格式也好,jpg格式也罢,作为位图,它们都有两个天然的缺陷:一是图片资源体积小与清晰度高这两者不可兼得;二是无论清晰度再怎么高,放大后依然不清晰。

我们可以简单感性地理解一下:位图是由很多个像素点构成的,理论上,位图的像素和屏幕上的物理像素一一对应,就可以达到最佳的显示效果。然而现在dpr>1的屏幕比比皆是,在这种场景下,位图的一个像素会由多个物理像素来渲染。在网页缩放时是更是如此,缩放厉害时一个位图像素可能横跨几百个物理像素。

这会带来两个问题:一是多个物理像素对应一个位图像素会显得很大,也就是所谓的“锯齿感”,二是这些物理像素并不能准确获取对应位图像素的颜色,很多取近似值的情况,导致颜色很杂。

我们从iconfont中找一个图标文件,下载其对应的png图片,通过放大来看看效果:

高清图标来袭!在vue项目中使用iconfont_第2张图片 高清图标来袭!在vue项目中使用iconfont_第3张图片

可以看到放大后,一是有不少“大方块”,二是出现了一些“近似色”。

为什么矢量图会更清晰?因为矢量图,比如svg,是一种对图像的形状描述,比如描述曲线、形状、颜色等,本质上属于文本文件,不仅体积小,放大后质量也不会下降。

怎么专挑图标下手

对矢量图来说,绘制的路径过于复杂,颜色过于丰富,也会导致绘制性能下降,这是矢量图的缺点,所以我们不可能拿矢量图去绘制一张广告背景图,但是图标却很合适,因为图标往往没有复杂的颜色信息,也没有像风景人像图那样复杂的线条。

在vue项目中试试阿里图标

  1. 打开阿里图标官网 https://www.iconfont.cn/
  2. 登录
  3. 新建一个项目
  4. 找几个图标,添加至项目
  5. 选择“Font class”方式引入,并下载项目到本地

选择Font class的原因一是语义化,二是通过类名来定义具体图标非常方便封装

高清图标来袭!在vue项目中使用iconfont_第4张图片 6. 将解压出来的文件夹重命名后放到项目的src/assets目录下(放在这里是因为assets目录在初始化的时候就被认为是一个用于存放静态资源的目录)

高清图标来袭!在vue项目中使用iconfont_第5张图片

  1. 现在可以开始着手封装

高清图标来袭!在vue项目中使用iconfont_第6张图片

如果你看过我之前关于echart封装那篇文章,就会发现我非常不推荐将封装的公共组件的单文件直接写在components根目录下,这是一个非常差的习惯。强烈建议再建一级目录,同时为你的公共组件写上README和使用示例,以及入参说明,这会极大的方便后续使用者的调用

封装之前的思考

在封装之前,我们需要考虑以下几点:

  • 可以通过type或者name入参来标识具体是哪个图标
  • 要提供最常用的样式入参,一个是图标颜色color,另外一个是图标大小size
  • 能响应事件
  • 使用者能定制一些特殊样式如旋转角度rotation,缩放倍数scale等
  • 如果在业务上有需要,做的更好一点,还可以提供dot和badge功能,也就是图标右上角的小红点和数量

能做到前四点,就已经完成了一个基础版图标组件的封装;如果能加上第五点,给这手封装打个90分,我认为没有问题。

封装的源码及说明

下面这个是没有dot和badge的,也就是一个青春版的图标组件封装,如果点赞超过10个,我会更新一个尊享版的。