尤大都推荐的组件库是如何开发出来的()

注意:为了让篇幅尽可能简洁一丢丢,在有些地方贴源码时,我尽可能贴最能反映要讲解内容的源码,其他重复性的代码就略去了,所以如果你自己尝试去阅读源码时,可能会发现和文章里的代码有出入。文章跑通 Naive UI 所用到的源码仓库为: https://github.com/pftom/naive-app
简洁的抽象 前端开发者现在几乎已经离不开 UI 组件库了,典型的如 Ant Design、Material Design、以及最近 Vue 生态兴起的 Naive UI 等,组件库提供了简单、灵活、易用的使用形式,如一个页面中最常见的 Button 的使用如下:

上述几行简单的代码就可以完成如下有意思的效果:
尤大都推荐的组件库是如何开发出来的()
文章图片

甚至是,可以一键切换皮肤,如 Dark Mode:
尤大都推荐的组件库是如何开发出来的()
文章图片

当然还可以处理事件、添加 Icon、处理 Loading 等,通过简单给定一些 Props,我们就可以拥有一个好看、实用的 Button,相比原始的 HTML 标签来说,实在是不可同日而语...
尤大都推荐的组件库是如何开发出来的()
文章图片

冰山理论 尤大都推荐的组件库是如何开发出来的()
文章图片

组件库在带来灵活、方便的同时,其内部的原理却并非如它使用般简单,就像上述的冰山图一样引人深思。
让我们翻一翻最近的 Vue 组件库新秀 Naive UI 的 CHANGELOG,就可以窥见编写一个入门的组件库大致需要多少时间:
尤大都推荐的组件库是如何开发出来的()
文章图片

可以看到,2020-03-21 就发布了 1.x 版本,而在 1.x 之前又是漫长的思考、设计与开发,至今应该差不多两年有余。
而为了跑通一个 Naive UI 的 Button,大致需要如下的文件或代码:
.|_____utils| |____color| | |____index.js| |____vue| | |____index.js| | |____flatten.js| | |____call.js| | |____get-slot.js| |____index.js| |____naive| | |____warn.js| | |____index.js| |____cssr| | |____create-key.js| | |____index.js|_____internal| |____loading| | |____index.js| | |____src| | | |____Loading.jsx| | | |____styles| | | | |____index.cssr.js| |____index.js| |____icon-switch-transition| | |____index.js| | |____src| | | |____IconSwitchTransition.jsx| |____fade-in-expand-transition| | |____index.js| | |____src| | | |____FadeInExpandTransition.jsx| |____wave| | |____index.js| | |____src| | | |____Wave.jsx| | | |____styles| | | | |____index.cssr.js| |____icon| | |____index.js| | |____src| | | |____Icon.jsx| | | |____styles| | | | |____index.cssr.js|_____styles| |____common| | |_____common.js| | |____light.js| | |____index.js| |____transitions| | |____fade-in-width-expand.cssr.js| | |____icon-switch.cssr.js| |____global| | |____index.cssr.js|____config-provider| |____src| | |____ConfigProvider.js|____button| |____styles| | |_____common.js| | |____light.js| | |____index.js| |____src| | |____Button.jsx| | |____styles| | | |____button.cssr.js|____assets| |____logo.png|_____mixins| |____use-style.js| |____use-theme.js| |____index.js| |____use-form-item.js| |____use-config.js

看似困难的背后 虽然跑通一个看似简单的