Component

F/A 方案

又一种利于跨端的组件结构方案
https://bytedance.feishu.cn/docs/doccnTgc0iGOVPubHZkwPpxXSNh
Semi Desigm 的跨JS框架方案正是以上思想的实践:将每个组件的 JavaScript 拆分为两部分:Foundation (与框架无关)和 Adapter(与框架强相关),以下简称 F/A方案。
这使得我们可以通过仅重新实现Adapter部分来跨框架重用 Foundation 代码,例如 React 、Vue、Svelte 或者WebComponent,快速打造不同平台上的通用组件库。
image.png

  • Foundation 层 (semi-foundation)

Foundation 包含最能代表 Semi Design 组件交互的业务逻辑,包括UI行为触发后的各种计算、分支判断等逻辑,它并不直接操作或者引用DOM,任意需要DOM操作,驱动组件渲染更新的部分会委派给Adapter执行。

  • Adapter 层 (semi-ui)

Adapter 是一个接口,具有 Foundation 实现 Semi Design 业务逻辑所需的所有方法,并负责 1. 组件DOM结构声明 2.负责所有跟DOM操作/更新相关的逻辑,通常会使用框架API进行setState、getState、addEventListener、removeListener等操作

常见方案
UserOperation、Component LifeCycle Change

  1. => EventHandler A / EventHandler B / EventHandler C + ……(一系列函数调用,每个function 一般包括取值、计算/判断逻辑、设值的组合操作。在常见的组件库实现里,ii 这类UI逻辑代码常与i、iii 这些框架api代码深深耦合在一起,所以针对不同框架进行移植的时候往往成本很大)
    1. getCurrentState
    2. Computed / Judge Logic
    3. setState
  2. => Dom Update

F/A方案
UserOperation、Component LifeCycle Change

  1. => Foundation f(n)
  2. => Adapter f(n)
  3. => Dom Update

    F/A 方案对于 react 来说相当于将 setState,ref 等内容交给 Adapter,逻辑与数据交给 Foundation

对比高亮部分,F/A方案将DOM更新前(在mvvm框架内一般为state / $data更新)的一系列取值、条件判断、设值操作进行了拆分并归类(如上图),将所有最终对dom操作/更新相关的都抽出来放在Adapter里

  1. Foundation functions部分,负责交互行为逻辑,包括各种计算、判断分支等逻辑的行为组合。其中需要dom操作的部分会委派给Adapter functions
  2. Adapter functions部分,负责所有跟DOM操作/更新相关的逻辑,通常会使用框架api进行setState、getState、addListener、removeListener等操作

    F 部分相当于对抽象后的组件,先定义行为,再填充改变数据的逻辑,初始的数据由外部提供,或拥有默认值

    A 部分提供与 Dom 操作功能相关的逻辑,数据驱动型需要将 F 中的数据进行转化,事件驱动型则不需要额外的转化,而如果 F 部分完全不定义数据,则需要将数据从 A 中读取,或用一个完全独立的数据管理方案,进行数据存放(证实:Semi从 A 中读取数据)。

    A 部分应该会混杂着 state 的定义 + setState 的各种周期函数(on/handle),行为函数(get/set/notify),会很奇怪。(证实:react相关行为,采用 context + hooks 进行定义,用 react 的依赖机制,决定各个周期函数的触发,所有的周期函数 + 行为函数,统一放入生成的 adapter(比较繁杂的周期定义,都在 adapter 中了,所以其实 react部分 与 adapter构造部分也是完全分离的)实例,注入 F 中,F 中自行调用行为函数。)

    所以其实是 F 部分通过读取 A 中的数据,利用 A 中的细分行为,生成抽象后的组件行为。F 是更高级的抽象层级,所有的基础设施都来自 A。理想状态 F 可以完全脱离 A 进行开发。 但 Semi 中缺乏对行为本身的抽象,相对 formily 中采用 batch,action 区分行为模式,computed ,observer 区分数据模式,需要更多的逻辑去处理这类问题。