实现Icon组件

344 阅读3分钟

概述

在实际项目中,多多少少会用到字体图标,在各种前端框架没出来之前,比较常用的字体图标库有阿里巴巴矢量图标库Font AwesomeIconPark等等,感兴趣的可以看看,在各种前端框架出来之后,对应的组件库都提供了字体图标,我们可以很方便通过组件使用组件库内置的字体图标,但是有时候组件库的字体图标可能满足不了我们的需求,因此需要我们自定义,现带你实现类似vue-design组件库中的icon组件,支持自己扩展。

最终效果

image.png

实现原理

本质上,组件库提供的字体图标,也是使用的第三方的字体图标库,比如iview就使用了第三方的字图标库 ionicons

具体实现

当前我们实现icon组件,基于阿里巴巴矢量图标库中的图标,自己可以根据需求自己变更。

下载字体图标

我们从自己喜欢的字体图标库去下载字体文件,我拿阿里巴巴矢量图标库中的图标下载为例子

  1. 找到自己喜欢的图标 image.png 2.加入购物车 image.png 3.点击购物车 image.png 4.添加至项目 image.png 5.下载我们添加的图标到本地 image.png 6.找到我们需要的文件添加到项目

image.png

组件目录结构

image.png

./MyIcon/iconfont

这个文件就是我们的字体文件,将上面下载的素材加到这里面来

image.png

  • fonts主要的字体文件,放这里
  • font.css定义字体我类名
  • icons.css所有字体的样式
  • variables定义字体组件的less变量

具体文件内容

font.less对应下载图标步骤中文件iconfont.css

@import "variables.less";
@import "icons.less";

// 定义字体
@font-face {
  font-family: @font-family; /* Project id 3582697 */
  src: url("@{font-path}/iconfont.woff2?t=1660701700431") format("woff2"),
    url("@{font-path}/iconfont.woff?t=1660701700431") format("woff"),
    url("@{font-path}/iconfont.ttf?t=1660701700431") format("truetype");
}

// 定义字体函数
.my-icon() {
  display: inline-block;
  font-family: @font-family;
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  text-rendering: optimizeLegibility;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  vertical-align: -0.125em;
  text-align: center;
}

// 调用字体函数给当前类加上类名
.my-icon {
  .my-icon();
}

icons.less对应下载图标步骤中文件iconfont.css

//记得加上我们组件的特定前缀my-icon-(可以不加,自己定义,后面接的就是字体文件的类名)
.my-icon-icon-shouye:before {
  content: "\e89f";
}

.my-icon-icon-shouye1:before {
  content: "\e70e";
}

.my-icon-icon-fenlei:before {
  content: "\e600";
}

.my-icon-icon-zaixian:before {
  content: "\e62e";
}

.my-icon-icon-online:before {
  content: "\e607";
}

.my-icon-icon-jigou:before {
  content: "\e61a";
}

.my-icon-icon-zuzhijigou:before {
  content: "\e66e";
}

.my-icon-icon-guanliyuan:before {
  content: "\e62a";
}

.my-icon-icon-cb-putongyonghu:before {
  content: "\e650";
}

.my-icon-icon-tushu:before {
  content: "\e65c";
}

.my-icon-icon-24gl-portraitMalePlus2:before {
  content: "\eb25";
}

.my-icon-icon-disanfang:before {
  content: "\e601";
}

.my-icon-icon-yonghuguanli_huaban:before {
  content: "\e62d";
}

.my-icon-icon-dingdan:before {
  content: "\e98d";
}

.my-icon-icon-rizhi:before {
  content: "\e617";
}

.my-icon-icon-minganci:before {
  content: "\fcf8";
}

variables.less

//定义文件路径
@font-path: "./fonts";
//定义字体名称
@font-family: "my-icon";
//定义自定义类名前缀
@prefix: my-icon;

MyIcon.vue

<template>
  <i :class="selftClasses" :style="style"  @click="$emit('click',$event)"> </i>
</template>

<script>
const classPrefix = "my-icon";
export default {
  name: "MyIcon",
  props: {
    type: {
      type: String,
      default: "",
    },
    // 字体大小
    size: {
      type: Number,
      default: 16,
    },
    // 字体颜色
    color: {
      type: String,
      default: "",
    },
    // 自定义字体
    custom: {
      type: String,
      default: "",
    },
  },
  computed: {
    // style属性
    style() {
      return {
        fontSize: this.size ? this.size + "px" : "",
        color: this.color ? this.color : "",
      };
    },
    // class类名
    selftClasses() {
      return [
        classPrefix,
        this.type ? classPrefix + "-" + this.type : "",
        this.custom && !this.type ? this.custom : "",
      ];
    },
  },
};
</script>

<style lang="less"></style>

index.js

//按需导出
import MyIcon from "./MyIcon.vue";
import "./iconfont/font.less";
export { MyIcon };

使用

使用的时候,直接复制下载的字体图标的font class就可以了,如果使用其他字体库的字体只需要将对应的文件下载下来,使用就可以了

        <my-icon type="icon-cb-putongyonghu" color="red" :size="30"></my-icon>
        <my-icon type="icon-fenlei" color="blue" :size="40"></my-icon>
        <my-icon type="icon-zaixian" color="green" :size="50"></my-icon>
        <my-icon type="icon-guanliyuan" :size="60"></my-icon>