引言
分而治之是软件工程中的重要思想,是复杂系统开发和维护的基石;组件化开发的最大价值是分治。
组件化
组件化是指解耦复杂系统时将多个功能模块拆分、重组的过程,有多种属性、状态反映其内部特性。
组件化是一种高效的处理复杂应用系统,更好的明确功能模块作用的方式。
组件粒度
划分的组件到底是什么粒度?按照原子设计原则,我们组件应分为五种:
原子组件
原子组价是组成所有组件的最基础的元素,具有不可再分特性。
如上图红色区域。一个按钮,一个文案,一个线,一个icon。
通常是游览器提供或者框架库内提供类似Button, Input(虽然有些是div模拟等实现,有些甚至很花哨,但组件设计语言上,不管什么样的Button都属于原子组件)
分子组件
分组组件是几个原子组件组成的组件。例:Label + Input 或者 Tabs。具有一定可操作性。
如上图蓝色框区域。
生物组件
生物组件由原子组件和分子组件组成,更专注于某一独立模块区域功能。例:列表, 日期选择,Dialog,等hl-ui里大部分组件。
如上图绿色框区域。
模板组件
模板组件由原子组件,分子组件,生物组件组成,更加完整的一块功能,如页面的基本信息模块,添加服务模块。
如上图黄色区域。
页面组件
页面组件是由以上所有组件完成。非常完成的一大块业务逻辑。
组件分类
基础组件
「基础组件」也可以被叫做「原子组件」或「通用组件」,是一种底层组件,其特点如下:
单一的不可再拆分的组件:比如一个 button,一个输入框,一个开关等。适用于各类业务场景:比如政务业务、电商业务、金融业务等业务都可以使用。可保证设计质量和效率:使用组件可以使设计稿具备较高的一致性,并提升设计和开发的工作协同效率。
主要指组件本身不包含任何业务逻辑,可被轻松复用的组件。
常见的模式是基于特定的前端框架(Vue、React等)实现一套通用的基础组件库,如Cube-UI、ElementUI等。在这类组件库中,通常会包括很多可复用于不同场景中的基础组件,例如:Tip、Picker、Toast、Dialog等。
这类组件在设计时,主要考虑对外暴露的prop、event等数据通讯、使用方式、样式等如何定义,以及组件与外部的交互形态,功能边界的划分等。
基础组件不应该与业务相耦合; 例如下面和全局数据相关的Button就是一个错误的用法
// 错误<button>{{globalState.text}}</button>// 正确<button>{{props.text}}</button>
业务组件
主要指与特定的业务场景耦合得更紧密的组件。
该类组件因视觉规范、交互风格、业务场景等的差异性,在大部分的情况下,只在一个业务场景下通用。当然也会存在复用的情况。
容器组件
容器组件因为需要对其它组件进行管理以及数据的分发所以它的拆分粒度通常是生物、模版或者页面。
从生物粒度上来讲,例如我们的form组件等就可以分类到容器组件。
从模版或者页面粒度上来看来看,每一个项目都是由一个个页面构成,每个页面一般负责一个独立的功能模块,各个功能模块组合完成了我们的整个业务系统。作为路由的渲染,一般不会复用,不会对外提供接口。
这类组件如果是按页面进行划分,主要的职责通常是:处理页面跳转、获取接口请求、处理各区块组件所需的数据等相关逻辑。
如何设计组件
1.整体视角——组件库整体
保证UI风格的统一性、交互的一致性,注重后期的可维护性
-
- 统一整套组件的颜色、文字、图标、分割线等的规范
- 不同组件的公共样式(颜色、字体大小等),抽取公共变量值表示,便于统一管理,以及后期可以统一更换主题
- 过渡动画、show、hide方法,抽取公共js模块,供所有组件使用
2.局部视角——单个组件的设计
独立性、完整性
关于独立性,每个组件的设计,为了要保持组件的纯粹性,尽可能做到:属性配置等API对外开放,但组件内部状态对外封闭,尽可能的少与其它外部组件耦合。
关于完整性,主要体现在,一个完整的组件需要具备以下几点
-
响应状态:考虑组件在不同尺寸下、不同应用场景中,应有的响应方案。
-
行为状态:考虑组件交互时,应暴露的事件或是呈现的状态。如:按钮应暴露点击等事件,且在hover的状态下,应呈现按压态的样式。
-
数据状态:考虑组件在多种状态下的表现。如:活动卡片在不同状态(未开始、进行中、已结束)下的展示
-
容错处理:
-
布局方面:考虑内部许多元素因为浮动、固定宽度、百分比宽度、文字行数减少等等,布局会错乱的问题
-
逻辑方面:考虑空状态、校验组件传入的Props参数缺少、参数不正确、网络错误、数据获取出错、极端情况等问题
3.拆到什么程度?
- 最小复杂度:单一职责
- 易于维护:逻辑清晰,易与定位问题
- 松散耦合:确保模块间的关系尽可能的简单
- 可扩展性
- 可重用性
- 精简性
- 层次性