ionic3开发——记一个使用自定义icon的方法

最近在使用ionic3Angular开发一款App。开发体验仍是挺好的。期间遇到如何在项目中使用自定义图标字体文件的问题,通过研究,找到了一个解决方法,记录一下。css

问题描述

ionic项目提供了一套丰富的图标库,在ionic3中也进行了升级。虽然很实用,可是在实际项目中,仍是须要根据视觉稿来增长图标。html

一般,咱们都会使用@font-face导入自定的字体文件。那么咱们怎么将这些图标融入到ionic3的项目中去呢?ios

下面以ionic3中的tabs组件做为例子,提出一种解决方式。git

话说问题是解决了,可是看起来其实并不优雅,不过能解决问题。=.=||github

理解ionic3中的图标组件

ionic icon的使用

ionic3中提供图标使用的方式有很多,其中很是重要的组件是:ion-icon,基本的使用方法以下:web

<ion-icon name="heart" ></ion-icon>

name属性是图标的名称,这样ionic就会在这个标签处渲染生成一个图标。其余的用法,还有:chrome

  • 根据不一样的设计风格使用不一样的图标(ios or md-->Material Design)浏览器

  • 设置图标的不一样状态app

  • 做为特定组件的属性框架

ionic也为本身的图标库提供了一个预览的页面,Ionicons

tabs组件中使用icon

在例子中,tabs组件使用图标的方式,是这样的:

<ion-tabs>
    <ion-tab tabIcon="heart" [root]='tabPage1'></ion-tab>
    <ion-tab tabIcon="alarm" [root]="tabPage2"></ion-tab>
    <ion-tab tabIcon="at" [root]="tabPage3"></ion-tab>
</ion-tabs>

经过设置tabIcon属性,就可使用图标库中指定的图标。

仔细看一下渲染后的html结构,你会发现,ion-tab实际上是在模板中加入了ion-icon组件:

渲染后的tabs组件使用了ion-icon组件

那么,ionic是如何根据一个name属性,就连接到他的图标库中的图标呢?

ionic使用图标的原理

因为ionic3使用了Angular做为框架开发,所以ion-icon要么是组件,要么是指令。因此咱们看看它的源码,是如何实现图标文件的使用的。

源码传送门:ion-icon

从源码中咱们能够看到,ionic把ion-icon定义为一个指令,有三个步骤:

  1. 进行平台风格(iosmd)判断和状态的判断。

  2. 根据判断的结果,将输入的图标名称,进一步组合成为以下形式的格式化文本

    ion-{平台风格标识}-{图标名}-{修饰}
  3. 将上一步获得的格式文本,添加到元素的class属性中。

至此,也很好理解了,经过一个css类,就可使用图标库中的字体定义(@font-face)

ionic将本身的图标字体的scss文件放在ionicons.scss中,定义字体名称为Ionicons

而图标库则成为另一个git项目,相关的类型放在ionicons-icon.scss中。在github中打开源码文件,ctrl+f搜索heart,能够看到css是这样的:

.ion-ios-heart:before { content: "\f443"; }
.ion-ios-heart-outline:before { content: "\f442"; }

经过伪元素,指明了对应的图标字体。-outline后缀指明的是轮廓形状的图标。

知道了这些,咱们就能够自定义字体文件和css类,从而让ion-icon也支持咱们自定义的图标了。

准备工做

图标文件

图标文件,通常你们都会用illustrator矢量设计软件设计,而后导出.svg格式的文件。

要打包成字体文件,也有很多工具,经常使用的是阿里出品的 iconfont。具体使用方法,网站上讲解的很是清楚,这里就很少说了。

当你上传本身的图标svg文件,导入项目,下载完成后,会获得一堆文件。
图标字体文件

有3种方式,可使用图标:

  • unicode 最原始的方式,可是兼容性好。

  • fontclass 使用伪元素和css类的方式,与ionic同样,兼容限制ie8+

  • symbol 惟一支持保留颜色的方式,可是兼容性须要考虑(支持svg的设备和浏览器能够)

在例子中,咱们选用fontclass足矣。

部署文件

将生成的字体文件拷贝到ionic项目src目录下assets中(具体目录根据项目的要求,这里只是例子)的fonts目录里。

而后,书写一份.scss文件,内容以下:

@import "ionicons-variables";

$jpicons-font-path: $font-path !default;

@font-face {
  font-family: "jp-icon";
  src: url('#{$jpicons-font-path}/iconfont.eot?t=1493779389504'); /* IE9*/
  src: url('#{$jpicons-font-path}/iconfont.eot?t=1493779389504#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('#{$jpicons-font-path}/iconfont.woff?t=1493779389504') format('woff'), /* chrome, firefox */
  url('#{$jpicons-font-path}/iconfont.ttf?t=1493779389504') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
  url('#{$jpicons-font-path}/iconfont.svg?t=1493779389504#jp-iconfont') format('svg'); /* iOS 4.1- */
}

.jp-icon {
  font-family:"jp-icon" !important;
  font-size:16px;
  font-style:normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

字体名和路径等等,根据须要自定义就能够了。

下一步,就能够定义本身的类名了,因为例子使用Material Design风格,所以,定义以下:

.ion-md-jpicon__evalTab:before { content: "\e64e"; }

.ion-md-jpicon__recTab:before { content: "\e650"; }

.ion-md-jpicon__storeTab:before { content: "\e651"; }

名字的定义按照以前提到的格式化文本的形式就能够,这里因为想说明清楚的缘由,我把名字定义的略复杂了一点,实际使用中能够按本身须要修改。

最后别忘了一点,在你的基础样式表,好比:app.scss中导入这个scss文件。

@import '../assets/fonts/jpicons.scss';

不管怎样,当你准备好这些文件时,下一步就可使用本身的图标字体啦。

使用字体

tabs组件中,能够很方便的使用定义好的字体:

<ion-tabs class="jp-tabs" >
    <ion-tab tabIcon="jpicon__storeTab" [root]="store" tabTitle="精选推荐" tabUrlPath="store" >
    </ion-tab>
    <ion-tab tabIcon="jpicon__recTab" [root]="recommend" tabTitle="应用场景" tabUrlPath="recommend" >
    </ion-tab>
    <ion-tab tabIcon="jpicon__evalTab" [root]="evaluation" tabTitle="深度评测" tabUrlPath="evaluation" >
    </ion-tab>
</ion-tabs>

在tabs组件的.scss文件中,咱们从新定义在该tabs组件下使用的字体名称:

.jp-tabs{
   .tab-button{
      &>ion-icon{
        font-family:"jp-icon" !important;   /*指定在当前组件中的ion-icon使用的字体名称*/
      }
  }
}

此外,若是有定义图标字体颜色的需求,简单粗暴的方式是:

.tabs-md .tab-button[aria-selected=true]{
  color:$jp-color;
  .tab-button-icon{
    color:$jp-color;
  }
}

当一个tab被选中时,ionic会修改对应组件元素上的aria-selected,值是true/false

运行ionic serve,查看渲染后的效果:

自定义图标后的tabs组件

再看html代码,能够验证上面所讲到的内容。

使用自定义图标后的html

总结

若是自定义组件和指令是否是也能够实现图标字体的使用?我想是能够的。

本文只是提供了一种方法而已,不太优雅,可是能够解决问题。好处是,可使用ionic中的一些关于图标的功能,例如,在tabs组件中,能够设置tabLayout属性来决定图标和文字的布局关系,若是要本身开发布局等功能,固然可行,可是须要花费时间。做为一种实现,本文的介绍也算做一种方式吧。但做为研究和推敲原理,我想应该更深刻的发现更好的方式。

我的能力有限,若是有什么错漏,请你们批评指正,以后会再补充内容。

相关文章
相关标签/搜索