关于下一代组件库的思考
在微信公众号上看到您的文章, 很兴奋, 对于您提出的这个问题, 我也思考过很多, 除了您提出并实践的分离转态之外, 还有接口继承体系以及ui代码自动生成需要完善, 这些都做了才能服务于下一代组件基础设施. 下面是我的详细论述, 但是这些都不重要, 重要的是我想加您的微信, 详细聊一下 ^-^
现状: 当前的web组件, 复用的基本单元为组件(类), 试图将所有需要的功能都封装在组件中, 并通过配置项的方式提供出来, 以方便使用者使用. 这种方式有以下三个主要问题:
- 封装所有的功能,这显然是个伪命题. 尤其在h5 的场景下, 定制化是刚需.
- 增加新的功能意味着增加新的配置项, 频繁变化的配置项对使用者来说是一种负担.
- 如果想要基于组件库做一些上层的封装系统, 需要对常用的组件库做适配, 成本极其高.
将具体实现与对外标准分离的web组件库编程技术, 制定了一套面向使用者的标准. 使用者只需关注标准, 具体的组件实现遵守该标准. 带来的好处:
- 使用者可根据需求的不同, 低成本实现定制化的组件.
- 新增功能是通过增加标准的具体实现来完成的, 不会新增配置项, 对使用者来说, 负担小.
- 如果想基于组件库做上层封装, 只需要遵守该标准就能兼容所有实现了该标准的组件库, 减少适配的工作.
以业界目前知名的组件库 AntdDesign 为例子 该组件库, 组织组件的基本单元是具体实现, 基本每种组件只提供了一个具体实现, 并提供了详细的 api 说明文档, 却并未定义对外标准. 随着组件库的升级, 功能的增加, 增加了越来越多的 api 配置项, 来满足不同的业务需求.
缺点: 1. 复用的基本单元是具体组件实现, 随着功能的增加, 具体组件变成了一个巨石组件, 体积越来越大, 极难维护, 且难以使用. 2. 为了满足不同的业务需求, 为单个组件增加了很多逻辑, 并通过 api 配置项对用户透出, 虽然增加的配置项都有默认值, 如果不使用对应的功能可以不关注. 但是这种通过扩充配置项的方式破坏了组件的通用性, 特别是当前 lowCode, 搭建系统, schemaToPage, 智能化等基于基础组件库的提效系统大发展的今天. 这些上层系统没有一个通用的组件库标准可以依赖, 只能依赖具体的组件, 导致上层系统与基础组件库强绑定, 使其难以成为成长为业界通用的方案. 3. 如果开发者有个性的话的需求, 由于现有组件库基本未考虑过扩展性问题, 导致很难扩展, 基本就只能改改样式, 如果想要增加个性化功能, 基本只能自己从零开始实现一个新的, 成本很高. 4. 随着功能的增加, "个性化"化的配置越来越多, 导致使用者的迁移成本及其高, 如果转换使用另外一套组件库, 又要重新学习另外一套个性化配置.
-
单个组件架构
如图1所示: 使用者只依赖于组件统一标准, 同时组件统一标准, 有可能会有很多具体实现. 比如 具体组件(默认提供), 这就是一个默认提供的组件. 如果使用者有一些个性化需求, 那么可以通过已有的通用逻辑, 当然也可以自己添加个性化的逻辑再加上个性化的 html + css 来实现个性化组件, 同时 由于个性化组件也是实现了组件统一标准, 所以对于使用者来说是无感知的, 低成本的. -
一个更加通用的场景
图2 是一个省略设计细节的关系图, 从上图可以很清楚的看出, 上层提效系统依赖的只是通用对外标准, 任何实现了通用标准的组件库都可以容易的接入上层提效系统. -
各组件之间的关系
图3是一个更接近真实情况的关系图. -
从上图可以看出上层应用不直接依赖具体实现, 而是依赖通用接口, 上层依赖可根据自己系统的需要依赖某个标准或者是标准的组合, 任何实现了某个系统依赖的标准或标准组合的组件都可以以很低成本被这个系统使用.
-
通用接口层, 为了保证标准的灵活性, 标准是由多多层继承关系组织的, 另外还有一些相对独立的标准, 比如受控组件标准, 或可以disable 标准等.
-
具体组件库可根据业务需求选择实现其中的某个或几个标准.
-
具体实现可以选择继承基础按钮组件, 以实现复用基础代码