前言
个人一直都比较喜欢阿里大佬提供的一些组件服务什么的,这里就只说图标管理吧,最开始的时候我是使用的https://icomoon.io 后面发现https://www.iconfont.cn/ 在以前开发是时候我们为了图片的请求少点,提升网站的性能会把这些小图标做到一张图上面专业叫法是雪碧图,后来随着前端发展有了字体图标,不啰嗦了吧,回到正题,由于上次icofont官网挂了之后,导致我的项目无法进行正常迭代,我就决定要自己弄个简单的图标管理。
需求
一般使用需要的是把设计做好的图标或者其他地方下载的svg图标上传到服务器然后可以查看,并且打包成一个js文件加载到项目中。
准备
都说天下文章一大抄,我也是去抄iconfont,我把iconfont的使用demo打开研究了一下。
我这里只说Symbol,通过分析看到就是我们需要在项目中引入./iconfont.js
iconfont把我们上传的图标进行了删减优化,最外层就一个svg标签里面使用了一个symbol标签来包裹之前的图标内容,每一个symbol的id都对应之前的svg图标名称。
❝iconfont也没有开源,具体怎么做的咱也不知道,只能知道目前这些信息了,然后就按照自己理解开始开发实现了
❞
前端开发
通过上面我们可以知道,现在我们前端需要的是把设计稿的svg图变成symbol里面的内容,打开svg图 可以简单测试下,直接把内容复制然后粘贴带了iconfont.js中,然后运行demo图标正常显示就说明是ok的,不然就是这样做是不行的。
通过图片我们可以看到,现在需要的就是把svg里面的path改成用symblo来包裹,在开发中svg图我们是通过文档流上传上来的,这个时候我们就需要对文档流进行操作,先把文档流变成字符串,然后js操作字符串拼接达到目的。
使用到FileReader和readAsText获取到字符串
const fileParse = (file) => {
return new Promise((resolve) => {
const fileReader = new FileReader();
fileReader.readAsText(file, "UTF-8");
fileReader.onload = (e) => {
resolve({ content: e.target?.result, name: file.name })
}
})
}
字符操作拼接我使用的是cheerio
const handleUploadSvg = ($, result) => {
let index = result.indexOf('<svg');
const str = result.slice(index);
const svgNode = $(str);
$('svg').attr('viewBox', svgNode.attr('viewBox'));
const findPath = svgNode.find('path');
if (!findPath.length) {
message.error('图标错误,不存在path')
return '';
};
findPath.each((i, el) => {
$(el).removeAttr('id');
});
const gDom = svgNode.find('g');
gDom.each((i, el) => {
const path = $(el).children('path');
const fill = $(el).attr('fill');
if (fill && fill !== 'none' && path.length && !$(path[0])?.attr?.('fill')) {
$(path[0])?.attr?.('fill', fill)
}
});
removeArrtId($, gDom);
if (gDom.length) {
$('svg').html(svgNode.html());
} else {
$('svg').html(svgNode.find('path'));
}
return $.html("svg")
}
通过上面的操作我们可以得到一个新的svg源码,图标显示还是flow
然后我把这个字符串传送给后端就行了
后端开发
后端要做的就是把我上传上来的svg字符串拼接到一起,然后以iconfont.js一样通过一个get接口返回给我就可以了, 通过浏览器可以访问到就说明ok了
其他两种需要用到些第三方库当时也有顺便研究看到了,如果有需要我再写一篇。