alibaba-fusion / next

🦍 A configurable component library for web built on React.
https://fusion.design
MIT License
4.59k stars 590 forks source link

分离组件的model与view #2113

Open csr632 opened 4 years ago

csr632 commented 4 years ago

背景

在基于fusion开发阿里云组件库的时候,我们发现有一些设计规范无法通过样式覆盖来实现,因为dom结构由本质的不同。举个例子,阿里云设计规范定义的DatePicker: image

弹层出现在input下面。

目前fusion的DatePicker: image

弹层盖在原本的input之上,并且弹层中渲染一个新的input。

通过修改fusion DatePicker弹层的位置,我们能得到最接近设计规范的版本是这样: image

可以看到,fusion的DatePicker中的2个input都出现了。两种设计规范存在DOM树结构上的差别。我们无法通过样式覆盖来实现阿里云设计规范。我们的Upload组件设计也面对着同样的问题

目前,为了实现设计规范,我们只能fork同一份对应的组件代码来修改。但是这意味着,放弃fusion未来的bugfix和feature,整个组件由阿里云自己维护。

问题原因

问题的根源在于,fusion的model与view层没有解耦。

目前fusion组件已经具备较强的可定制性,目前的可定制性来自于:

但是即使上述这些手段再强大,也无法达到定制DOM树结构的程度。这是目前fusion可定制性的上界。

因此,当遇到一个新的设计规范时,总是能发现很多无法通过上述方式来定制的地方。上面的阿里云设计规范就是一个例子。

为了实现无法定制的样式,下游组件库只能fork一份组件代码。为了对view层做一点点的调整,我们要同时放弃这个组件状态管理(model层)逻辑。这不利于fusion对集团组件库进行收敛。

解决方案

对组件的model层和view层分离。model层做状态管理,不负责渲染任何DOM节点,view层根据model层提供的状态来渲染DOM树。

事实上,model层和view层的分离在组件库中早有雏形,比如

当view层的灵活性无法支持下游设计规范时,下游组件库可以自己实现view层,同时复用model层。相比fork一份组件代码或者自己重新实现,下游组件库显然会倾向于使用fusion提供的model。

方案实施策略

按需重构。

比如阿里云这边遇到了DatePicker的问题,希望自己实现view层,同时复用DatePicker的model层。因此我们有意愿给fusion提PR,将DatePicker重构成model与view分离的结构(毕竟这样做比fork一份DatePicker代码要好得多!)。其他下游组件库接入fusion的时候也同理。

fusion-design-bot commented 4 years ago

Hi @csr632, 非常感谢您的反馈,但是由于您没有使用 创建 issue 页面提交,当前issue将直接被关闭,谢谢! Thank you for your feedback, but we have to close this issue because it's not generated by our page

csr632 commented 4 years ago

这个文档我已经放在语雀上了,以那里的为准吧。 https://yuque.antfin-inc.com/multix/module/cr7eb2