0x1 问题
iconfont 应该是挂了有 1-2 两个月了,不论是因为什么起因,必定会有一大堆的我的项目有一阵子图标出不来。
作为开发者以来就始终有个感觉,那就是在线服务都不牢靠。我的项目中第三方服务越多,更多不可控的因素就越多。如果都是在本人的服务器上,至多我能够管制服务启动,敞开。都是在同一时间,而不会呈现这种能用,然而又没有齐全能用的状态,这比服务挂了还恶心。
Node 创始人新搞的 deno 也反对引入在线的脚本,我看到这段代码第一工夫不是居然还能这样写,给我的第一感觉就是这代码某天可能就挂了,导致整个我的项目起不来。
import { VERSION } from 'https://deno.land/std/version.ts'console.log(VERSION)
0x2 须要达到的成果
因为是 uni-app 开发的我的项目,且须要兼容 app 和 nvue。因而图标只能应用单色字体图标的模式,无奈间接应用 svg 的模式。
- 本地导入,不依赖任何的第三方
- 反对 weex 的 nvue 界面
- 兼容 h5 和 app 的显示
- 组件模式应用
- (web 也是差不多的思路,这里以 uni-app 为例)
0x3 解决思路
既然在线服务不牢靠,那么必定是应用本地导入形式了。当初的 iconfont 是无奈应用,无奈上传和下载。看看还有什么方法将 svg 转换到字体图标了。github 上有不少将 svg 转换到 webfont 的库。
- svg2ttf
- svgtofont
我尝试下载了几个测试,发现都存在一个问题,就是我从 MasterGo 导出的 svg 图标应用这些工具进行转换的话,在我的项目内应用始终是一坨彩色的。猜想是 svg 须要进行一些解决。因为我从 iconfont 下载一个 svg 下来进行转换是 ok。这里不开展说,也不是本人善于的方向。如果你想理解 iconfont 做了什么能够看看这个
- iconfont 字体生成原理及应用技巧
外面讲的比拟具体,字体图标解决其实有很大的学识,图标很小,做的事件可不少。
0x4 icomoon svg 解决
这是一个相似于 iconfont 的平台,毛病就是只能本地保护,所有的数据都存在缓存,如果清理了浏览器缓存数据就被革除了。不过这个反对我从设计图间接导出的 svg 进行解决。这里以 MasterGo 进行演示实际上就是获取 svg 图标的过程。
4x1 文件改名
首先让 ui 整顿好我的项目内用到的图标,命名好。能够让我间接导出成为 svg。
4x2 上传到 icomoon
拿到导出的 svg 图标,上传到 icomoon。点击 icomoon app 进入 icomoon
导入 svg 图标
抉择从 MasterGo 导出的图标,上传
选中所有的图标点击生成字体
点击预设设置为 class 选择器,勾销反对 ie 8,点击 download 下载字体包
4x3 拿到导出的文件
看起来和 iconfont 导出的没啥区别。
0x5 图标组件
c-icon-moon.vue
一般的 vue 组件,外面的 #ifdef
写法是 uni-app 的条件编译。为了兼容多个平台须要应用到条件编译。
<template> <!-- #ifdef APP-NVUE --> <text @click="onClick" class="icomoon" :style="iconStyle">{{ icons[name] }}</text> <!-- #endif --> <!-- #ifndef APP-NVUE --> <text @click="onClick" class="icomoon" :class="name" :style="iconStyle" /> <!-- #endif --></template><script>// #ifdef APP-NVUEimport icons from './icons'// #endifimport { addUnit } from '@/utils'export default { name: 'CustomIconMoon', props: { size: { type: [Number, String], default: 'inherit', }, width: { type: [Number, String], default: 'auto', }, weight: { type: String, default: 'normal', }, height: { type: [Number, String], default: 'auto', }, color: { type: String, default: '#909399', }, name: { type: String, required: true, }, rpx: { type: Boolean, required: false, default: false, }, bubble: { type: Boolean, required: false, default: true, }, }, computed: { iconStyle() { return { fontSize: this.size === 'inherit' ? 'inherit' : addUnit(this.size, this.rpx), width: addUnit(this.width, this.rpx), height: addUnit(this.height, this.rpx), color: this.color, 'line-height': addUnit(this.height, this.rpx), 'font-weight': this.weight, } }, }, methods: { onClick(e) { this.$emit('click') if (!this.bubble && e) { e.stopPropagation() } }, }, // #ifdef APP-NVUE data() { return { icons: icons, } }, // #endif}</script><style scoped>/* #ifndef APP-NVUE */@import './style.css';/* #endif */.icomoon { font-family: icomoon;}</style>
addUnit 办法
// 增加单位,如果有rpx,%,px等单位结尾或者值为auto,间接返回,否则加上rpx单位结尾export function addUnit(value = 'auto', rpx = false) { value = String(value) return isNumber(value) ? `${value}${rpx ? 'rpx' : 'px'}` : value}/** * 验证十进制数字 */export function isNumber(value) { return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)}
icomoon-ttf-base64
为了兼容 nvue 须要将 fonts/icomoon.ttf
文件转换为 base64 写入到该文件
转换网址:https://www.giftofspeed.com/base64-encoder/
export default 'AAEAAAALAIAAAwAw...`
icomoon.woff
icons.js
这里配置 nvue 须要显示的图标名字。
\ue912
相似的字符能够关上 style.css
找到你须要在 nvue 显示的图标名字复制。
/** * 这里配置须要在 nvue 显示的图标 */export default { // 指纹 'icomoon-fingerprint': '\ue912',}
nvue-helper
nvue 须要的初始化配置。
import icomoonTtfBase64 from './icomoon-ttf-base64'/** * iconfont 须要用ttf转base64 * 转换网址:https://www.giftofspeed.com/base64-encoder/ */export function onInitNvueFontIcon() { const dom = uni.requireNativePlugin('dom') dom.addRule('fontFace', { fontFamily: 'icomoon', src: `url('data:font/truetype;charset=utf-8;base64,${icomoonTtfBase64}')`, })}
style.css
删除不须要的格式化,只留下 src: url('icomoon.woff') format('woff');
这一段就行。
@font-face { font-family: icomoon; font-style: normal; font-weight: normal; font-display: block; src: url('icomoon.woff') format('woff');}.icomoon { font-family: icomoon !important; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-style: normal; font-variant: normal; font-weight: normal; line-height: 1; text-transform: none;}.icomoon-add::before { content: '\e900';}/* ... */
0x6 应用
vue 界面
间接参考 组件应用示例 就能够。
Nvue 界面
nvue 界面应用须要导入字体文件,全局只须要导入一次就行了
App.vue
<script>// #ifdef APP-NVUEimport { onInitNvueFontIcon } from '@/components/c-icon-moon/nvue-helper'// #endifexport default { onLaunch() { // eslint-disable-next-line no-console console.log('App Launch') /** * Nvue 启动解决 */ // #ifdef APP-NVUE onInitNvueFontIcon() // #endif }, onShow() { // eslint-disable-next-line no-console console.log('App Show') }, onHide() { // eslint-disable-next-line no-console console.log('App Hide') },}</script>
组件应用示例
其实就是 vue 组件的应用了。这里贴一个示例。
<c-icon-moon size="60" name="icomoon-fingerprint" color="red" />
显示成果
iconfont 正名
这里为 iconfont 正名一下,先看下网友的情绪 https://github.com/thx/iconfont-plus/issues
阿里是大,但不是什么部门都大,外部是有估算调配的,人家是企业,不是慈善机构。从应用 iconfont 这个平台以来始终都是白嫖,精确来说如同没有付费我的项目。
再来看看明天用到的 icomoon 平台订阅费用,当然是举个例子,有多少公司违心在 icon 上有这个估算的呢?
评论区留给大家。
开发日记系列
只记录些平时开发感觉有用的货色,有问题请务必斧正,托付了
- 开发日记(01) - uni-app 应用等宽字体对其数字显示
- 开发日记(02) - js 异步工作队列
- 开发日记(03) - uni-app 打包为 app
- 开发日记(04) - iconfont 挂了,我的项目内的图标怎么办?
对于我
SunSeekerX,
全栈开发、区块链开发、挪动端开发、前后端开发、NodeJS 开发、小程序、uni-app
开发、等
喜爱探讨技术实现计划和细节,完满主义者,见不得 bug
。
Github:https://github.com/SunSeekerX
集体博客:https://yoouu.cn/
集体在线笔记:https://doc.yoouu.cn/