共计 4924 个字符,预计需要花费 13 分钟才能阅读完成。
📌 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 图标的过程。
4×1 文件改名
首先让 ui 整顿好我的项目内用到的图标,命名好。能够让我间接导出成为 svg。
4×2 上传到 icomoon
拿到导出的 svg 图标,上传到 icomoon。点击 icomoon app 进入 icomoon
导入 svg 图标
抉择从 MasterGo 导出的图标,上传
选中所有的图标点击生成字体
点击预设设置为 class 选择器,勾销反对 ie 8,点击 download 下载字体包
4×3 拿到导出的文件
看起来和 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-NVUE | |
import icons from './icons' | |
// #endif | |
import {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-NVUE | |
import {onInitNvueFontIcon} from '@/components/c-icon-moon/nvue-helper' | |
// #endif | |
export 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/