Semi Design - UI组件库如何分层设计,使其具备适配多种mvvm框架能力
Semi Design (https://semi.design)是由抖音前端与 UED 团队维护,致力于高效连接设计师与开发者,打通 DesignOps & DevOps,提供高度定制化能力的现代设计系统。
当我们决定要从0到1 打造一个设计系统的时候,面临的首要问题必然是技术选型。在当前阶段,前端组件库选型要回答的第一个问题:我要基于哪个JS框架来实现?这一问题的答案往往与前端团队本身已有技术栈选型,团队成员偏好等强相关。
但就Design System设计语言本身而言,是与技术实现无关的。所以我们会看到诸如无论是material design、ant design除了官方提供的React、Angular版本外,社区还衍生出了Vue、Svelte、Blazor等多个基于不同技术栈的实现版本,本质上属于同一种设计语言,在不同技术栈上的表达。
在JS GUI library的实现历史上,无论是jQuery时代,还是当前mvvm类框架时代,大多数组件的交互形式并没有发生根本性的变化,仅仅是基于不同的语法重新实现逻辑封装。那么是否有一种GUI实现方式,write once,run anywhere,兼容不同的框架呢?
我们首先想到的自然是WebComponent,得益于自定义元素,shadow dom等特性,它在打造组件库方向,具备天然的优势,特别是作为library被不同框架的应用层所消费时,具备更强的通用性,无需关注宿主应用的前端框架选型。然而当前阶段,无论是浏览器兼容性还是上下游工具链,WebComponent都不够成熟,尚无法大规模在生产环境中直接应用。从面向未来的角度看,WebComponent的生态早晚会走向成熟,当它逐渐稳定后,如果我们又需要重新将所有组件逻辑实现一遍的话,其实是在做重复工作。
如果我们现阶段就将抽象程度进一步提高,以可跨框架作为要求,将所有实现逻辑拆分为框架强相关 + 框架无关,分离render function 与 handler function。是否可以显著降低我们在不同框架间迁移的工作量,从而低成本地实现多框架支持呢?
我们以Select 选择器组件为例子分析一下它的交互行为
- 收集optionList/children,构造出候选项列表
- 根据defaultValue/value,计算出哪个候选项该被高亮选中,若两者均为空,则直接展示placeholder