Table of contents
展开目录
目录
源码
本文只讨论 svg icon 图标组件库的实现,
如果你更喜欢通过 iconfont 等生成字体文件后使用样式来处理图标,
完全可以忽略本文。
组件库为什么要从图标开始?
在我看来,图标贯穿了整个组件库,对于组件库来讲,不仅需要提供一套图标,还要支持使用者自定义图标。
只有把图标落地,才能正式的开发组件库。
Svg-icon Component
同步组件
一个最基本的 Svg-icon,大概是这样,将 svg 文本直塞到 <template>
中即可:
异步组件
如果想使用 svg 文件又改怎么做呢?
这个需求必须上一点魔法才能实现
想要在 vite 中能 import("icon.svg")
,就需要安装并开启 vite-svg-loader
:
使用 defineAsyncComponent 实现一个异步的 Svg-icon:
解耦 Svg-icon
现在市面上的第三方组件库,会将图标抽离出来,单独封装成一个 package。
为什么不将 Svg-icon 和组件库放在一起维护和发布,而要单独抽离出来呢?
- 有条件的公司会制作一套定制化的 Svg-icon,不会用到组件库所提供的 Svg-icon;
- 图标与组件库解耦,可以更好的维护和更新图标资源,图标库单独发版不会影响组件库;
- 解耦后,组件库构建后的体积会大幅减少;
解耦之后,整个组件库就变成两个 package:
使用 scope
的方式来命名,例如:
@whouu/geist-design
@whouu/geist-design-icons
同理也可以继续扩充相关的包,例如专属的 eslint 配置:@whouu/geist-design-eslint
等等。
搭建 Icon-package
使用 vite 初始化仓库:
稍微改造一下目录结构:
App.vue
用来调试图标组件;
index.ts
用来导出组件;
vite.config.ts
使用库模式打包组件;
使用库模式打包,需要调整一下 vite.config.ts
:
以这份 vite.config.ts
文件进行构建,构建产物是这样的:
在 package.json
中,我们需要针对 ./dist/
中的产物来声明库的一些入口、导出等 key/value
:
*.umd.js
可以通过 <script>
标签引入,也可以通过 require(CommoJS)
引入;
*.es.js
则是通过 ESModule
引入;
- 如果设置
type:module
,类型声明文件需要写在 exports
中;
feather-icons
对于 svg 的资源,有条件可以由公司设计制作,或者在 iconfonts 统一导出,
也可以像我这样,使用 feathericons,它包含了**200+**的资源文件。
多写几个图标组件后,你就会发现,除了 svg 内容不一样外,其他的所有东西都是一致的,都是复制粘贴。
所以我们需要一个通过样板代码自动生成组件的脚本:update-icons.js
:
- 从 feathericons 拿到所有的
icons
;
- 通过模板字符串声明 SFC 的样板代码;
- 遍历
icons
并扩展组件名;
- 遍历
icons
并结合第二步的样板代码生成文件并写入 components/
;
- 写入完毕后更新
index.ts
导出组件;
执行 npm run ./scripts/update-icons.js
,我们便立即拥有了 feathericons 的全部 Svg-icon。