前言
最近,在 BuildAdmin 项目的开发中,我们规划了一个 Icon
组件,我们希望通过这个组件,能直接同时使用多种图标库的图标(一种语法,实现无限的图标扩展和高度兼容性)并且,实现该 Icon
之后,理应还有一个图标选择器
,可以加载出不同图标库的所有可用图标,方便直接选择使用,文末提供完整代码。
由于项目是基于
Vite
的,所以本文会出现少量只在Vite
下才能运行的代码(vite专有api等)。
我们的Icon
和Icon选择器
组件,实现了以下常用图标库的支持,如果还有其它你喜欢的图标库,可以参考我们的实现方式,自行加上即可。
- 本地SVG图标:直接将svg文件放入指定的文件夹内,实现自动加载该文件夹所有的svg,并利用
Icon
组件直接使用,无需手动import
。 - ElementPlus的icon,首先使用官方提供的方法全局注册,然后和
Icon
组件整合,实现语法的兼容性。 - Iconfont(阿里巴巴矢量图标库),实现了自动载入
Font clas
(css链接,载入后即可通过class来使用对应的字体图标),实现Icon
组件的语法兼容性,然后自动解析出Font class内的所有图标名称,以供图标选择器使用。 - FontAwesome,这是一款很常用的图标库,包含了675个图标,
Icon
组件实现了自动加载,语法兼容;并且自动解析所有图标名称,以供图标选择器使用。
使用四种图标的语法
<!-- 本地图标 --> <Icon name="local-图标文件名" size="18px" color="#000000" /> <!-- Element Plus图标 --> <Icon name="el-icon-图标名" size="18px" color="#000000" /> <!-- FontAwesome图标 --> <Icon name="fa fa-图标名" size="18px" color="#000000" /> <!-- Iconfont图标 --> <Icon name="iconfont 图标名" size="18px" color="#000000" />
复制
具体实现
目录结构
BuildAdmin ├─src │ │ App.vue │ │ main.ts | | vite.config.ts │ ├─assets │ │ └─icons 存放本地SVG文件的文件夹 │ ├─components │ │ ├─icon │ │ ├─svg │ │ │ ├─index.ts 加载本地SVG文件的实现 │ │ │ ├─index.vue svg显示组件的实现 │ │ ├─index.vue Icon 组件的实现 │ │ └─selector.vue 图标选择器组件的的实现 | ├─utils │ │ └─common.ts公共辅助函数库
复制
本地SVG
我们准备了一个目录/src/assets/icons
,将svg文件放入其中,实现自动加载全部文件(不依赖第三方包),并直接以:<Icon name="local-图标文件名" />
的语法使用图标。
第一步:SVG文件读取准备
文件:/src/components/icon/svg/index.ts
// 从fs库导入读取文件和读取文件夹的函数 // fs库是node自带的,无需通过npm进行install import { readFileSync, readdirSync } from 'fs' // 定义一个变量以保存所有的icon文件名称 let iconNames: string[] = []
复制
众所周知,svg文件,是以XML的语法定义的矢量图片文件,我们需要对svg的XML内容进行一些特殊处理,比如清理掉width、height
属性等,我们定义了一些正则表达式,读取到svg文件内容之后,将这些正则匹配结果进行处理:
const svgTitle = /<svg([^> ].*?)>/ const clearHeightWidth = /(width|height)="([^> ].*?)"/g const hasViewBox = /(viewBox="[^> ].*?")/g const clearReturn = /(\r)|(\n)/g const clearFill = /(fill="[^> ].*?")/g
复制
接下来,我们首先实现一个查找SVG文件的函数(递归),将svg文件内容构建为symbol
元素
function findSvgFile(dir: string, perfix: string
复制