UI设计师必看:详解最全面的组件化开发与设计指南

组件化其实是一个很早就有的概念了,并不多稀奇,也不难理解。尤其是对于编程开发人员而言,对此应该更是熟悉。而今天这篇文章,我作为一个UI设计师来谈谈我对于组件化开发与设计的一些想法,从而帮助设计师们了解程序员是如何进行组件化开发的,怎样的设计才能更好的方便程序员快速落地实现,你又应该提供哪些设计文件,协助程序员组件化开发。难道只是效果图和切图吗?肯定不是。

什么是组件化?

组件化在我的理解来看,有点类似于搭积木,如上图所示,每一块积木就是一个组件,是既独立又统一的。因为独立,所以它可以自由组合,也可以随意替换和删除其中一个组件,并不会影响整体。但是它又统一于整体,比如上面的积木都是六边形的,你不可能拿一个三角形放进去啊。而组件化就是说,一个整体项目就是由无数个独立的组件搭建起来的。组件化的工作方式信奉独立、完整、自由组合。目标就是尽可能把设计与开发中的元素独立化,使它具备完整的局部功能,通过自由组合来构成整个产品。

设计师为什么也要有组件化思维呢?

我先来说说,组件化对设计师有什么好处?

1. 符合产品功能逻辑;作为一个UI设计师,设计最重要的一点就是要符合产品功能逻辑,绝不是所谓的“好看”。而组件化的设计理念恰恰是最能帮助设计符合产品功能逻辑的。

从实践验证来讲,特定类型的信息,就有特定的最优展现方式和交互方式,这叫做设计模式。设计模式就应该提取出来作为组件。比如要从多个维度快速检索和对比大量数据,没有什么能比表格形式效率更高。想象一下,下面这个界面的表格数据,做成卡片式堆叠在一起,划一张换一条。或者像淘宝商品列表那样,一行4列平铺开。那还对比个P啊,用户都要摔鼠标了。

2. 有助于保持交互一致性;比如说,在一个项目里,选择日期应该是统一的交互方式,在整个产品中就应该只有一种存在形式。所以时间选择器就是一个组件,一个可以复用的组件。如果你没有组件化思维,很可能出现好几个不同的时间选择器,一会儿是滚轮拨盘,一会儿是日历,一会儿又是下拉列表,这样的设计绝对是不能上线的。当然,该统一的地方还有很多,比如:错误提示的形式,进度条的交互方式,导航栏和按钮的样式,表单,下拉菜单等等。

3. 保持视觉风格的统一;这部分主要是视觉方面的考虑,更多样式上的差异,不同的样式会给产品带来不同的调性。

就拿下图按钮来说。圆头造型表现出一种柔和亲切的特质,同时有利于将注意力聚焦到其中内容上。而直角则展现出一种棱角分明的硬朗,边界更加清晰。想一想三星手机和锤子手机的外观造型,两种截然不同的感觉。为了保持产品视觉风格统一,设计师应该找到最合适的方案,并处处保持统一,不可以太随心所欲。比如说,在类似的界面中,有的按钮是方的,有的按钮却是圆的,这怎么能行呢?甚至于同一产品中,不同界面的下拉菜单样式都不一样,这也绝对是不行的。

4. 便于多设计师协作;组件化设计是大型设计项目的必要条件。

比如两位设计师协作,一个在设计注册界面,一个在设计修改密码界面,或者在设计某个问卷调查的弹窗。这其中都有表单,两个人设计出来不一样怎么办?一个边框颜色深一点,一个边框颜色浅一点?表单的点击反馈效果一个是黑色表示触发输入,一个是主色表示触发输入?其实没理由不同,应该保持一致。口头约定太麻烦,而且难以保证执行到位,组件化就是最好的解决方式。

5. 便于修改设计;设计总是需要修改优化的,有些改动牵扯全局,动静非常大。

比如管理后台的界面,左侧的主导航是全站通用的。某天决定要给它换一套浅色的设计,难道每个源文件都改一遍吗?如果产品逻辑复杂,源文件有上百个呢?你准备一个个的改到什么时候呢?3天?5天?甚至几个礼拜,时间就会都花在这种无意义的重复劳动上了。但是如果你一开始就依照组件化设计,那么对于设计的修改就会是非常方便的,你只需要将主导航这一个组件改为浅色即可。改这么一个组件的颜色,你甚至一分钟都不用就搞定了。剩下的时间,可以用来干嘛呢?用来构思思考设计样式,交互方式,优化你的设计,这才是设计师应该做的。

开发人员为什么也要有组件化思维呢?

下面讲讲组件化对开发的意义。其实开发同学从中受益会比设计师更多。因为组件化开发绝对可以大大提高工作效率,减少加班时间的。不加班了,开发同学们,你们终于可以打游戏泡妞出去浪啦。

1. 降低耦合度;降低耦合度,相信这是大型项目都在追求的。

举个例子,如果要把页面的body区域加宽。内部许多元素因为浮动、固定宽度、百分比宽度、文字行数减少等等,布局会乱套。就像下图里这样,这是因为内部模块的样式对页面父级元素存在依赖和继承。

可能有人会觉得并不存在依赖关系,但其实固定宽度本身就是一种依赖关系。假如说页面主体部分宽度1000px,左侧边栏200px,右侧800px。没错,这是按设计图来做的。那这个800px宽是怎么得出的?正是因为页面主体宽度1000px,才找了个合适的左右比例,设计成这样的。所以无可避免,从设计这个环节开始就产生了依赖关系。像这种情况,我宁可在模块外面多套一层容器,模块本身的宽度写成100%,外面那层容器属于框架布局,具体宽度写在它上面。虽然DOM树变复杂了,但内外的布局逻辑被分离了。

2. 减少冗余;页面中所有<table>标签,都可以使用同一套css,不必每个页面单独定义。

比方说要新增一个带表格的界面,开发同学按照设计的效果图一行行写页面。但是如果在某个已有界面中就存在表格?或许当时是另一位开发同学做的。相比重新写一遍,把代码要过来直接用更方便一点吧?如果表格样式之后又要改呢,是不是两个地方都得改。如此一来,用到表格的页面越多,就越容易漏改。而且静态资源服务器上存了太多份关于表格的样式,其中内容明明是一样,这就会导致代码越来越冗余。

3. 优化性能;优化性能刚好可以接着上一条说。那么多份表格的样式,客户端每打开一个新的表格页面,就得加载一次。占用带宽,浪费了缓存资源。虽然一两个的影响几乎感受不到,但这种情况一多,就会对用户体验产生明显的影响。慢,是用户体验的头等大忌,没有之一。应该是按需加载资源,一个简单的登录页面,没有必要加载整站的css与js代码,拖慢速度。

4. 便于多开发协作;这和设计师协作的道理相同。如果两个开发同学都在制作带有下拉菜单的页面,这部分工作只要交给其中一人就行了。TA做好之后封装成组件,另一位开发在自己的页面中加载就行了。

5. 便于查错;这便于查错,是耦合性降低的一个副产品。它可以大大加快错误排查的速度。如果页面上出现问题,可以找出每个可能有关的组件,逐个拔除,直到恢复正常。这样就能迅速锁定错误发生的位置。同时组件内也可以形成完整的自测单元,也方便了测试工作。

如下图,突然出现某个弹窗样式错乱。如果采用组件化开发,只要检查弹窗这个组件的代码,如果是这部分代码出现问题了,只需要解决这部分代码就行了,如果弹窗组件没有问题,则说明不是弹窗代码导致的bug,不需要解决弹窗,而是去排查别处的代码,这样就能大大缩小排查范围。

6. 便于修改;假如设计师每个页面改同一个地方要花一个小时,那开发做同样的事情至少要花一个上午,至少!封装成组件,可以把这个时间缩短到10分钟。毕竟不用去改几十个页面的HTML、CSS和JS,改一个组件就可以了。比方说,来了一个新需求,要求所有页面的标题字号都要加大,开发同学如果不按照组件化开发,那就要一个个页面的改了。我想这就是别的开发可以出去浪,而你却要不停地加班的原因之一吧。

设计师要懂的页面布局原理

讲了组件化的意义,本来顺理成章应该讲组件化的具体做法。但在这之前其实有必要插入这一块内容,帮助没有前端基础的设计师了解,开发是如何把页面搭建起来的。大家可以先有一个粗略的想象,就像是重力朝上的俄罗斯方块。页面元素都是从下往上这样一行一行搭出来的,不过这个玩家有强迫症,他一定会从左上角、右上角或者中间位置搭起。当然……搭满一行并不会消除。 ¯\_( ツ )_/¯

布局原理:

1. 行内元素与块元素;这网页布局中有两个概念:行内元素和块元素。它们是非此即彼的关系,网页里只要是你能看见的东西,一定不是行内元素就是块元素。

这两种元素的表现略有不同。图中虚线框代表一行,但实际上这是不可见的,只是我为了说明布局方式画出来的,其中的绿色矩形才是页面上真实可见的元素。

如上图,我们看第一行,这里有3个行内元素。内容长度不同,它们表现出来的宽度就不同,这是一种会随内容变化而改变尺寸的布局单元,而且它们总是从左到右横向排列,只要一行里排得下。再看第二行,这里只有1个块元素。你看它内容很短,就三个字,却占了一整行。没错,块元素就是这么任性。就像自习室一卷厕纸占一排座位那样。最后看第三行。浅绿色是一个块元素,深绿色是它内部的元素。所以元素之间是可以嵌套的,无论多么复杂的页面,都是这样一层层嵌套形成的。但是要注意,块元素内可以嵌入行内元素和块元素,行内元素只能嵌入行内元素。请看其中的深绿色部分,第二行是一个块元素,设定了宽度,并且居中排列。其实前两个行内元素的右边明明有空间,而且右边还放得下一个行内元素。但即使如此,它还是要占一整行。当然,块元素这个独占一行的特性有例外,我们接下来就会说。

2. 浮动;刚才讲的是常规的布局方式,我们现在讲两种打破常规的方式。

如下图所示,浮动有两个方向,向左和向右。被加上了浮动属性的元素,表现都会变得类似于行内元素,根据内容变化尺寸。第一行的左右浮动元素都可以是块元素,但它们却排在了一行里。第二行和第三行是一组对比,表现了非浮动元素与浮动元素混合排列时的规则。第二行的文字是一个常规布局的元素,可以看到左右浮动的元素各就各位,常规布局的文字很灵活地填充空隙,就像报纸排版一样。而第三行里的情况,文字段落也加上左浮动属性,并且限定宽度,它就会跟在左浮动元素的右侧。当然,如果文字不限定宽度,它还是会独占一行,因为文字足够多。这和块元素独占一行的道理不同,它仍然带有浮动属性,本应该跟在左浮动元素的右边。只是因为自身宽度太大,一行挤不下了。

3. 绝对定位;另一种打破常规的布局方式是绝对定位。

这就毫无章法可言了,像狗皮膏药一样想贴哪里贴哪里,还可以像下图里这样层叠着贴。总之,绝对定位的元素不会占据常规布局和浮动布局中的任何空间,而是直接挡住它背后的内容。不过既然可以层叠,就有谁在前谁在后的问题。这和设计工具里的图层是一样的,当然有办法可以控制。

一个页面是如何搭建出来的?

为了让大家看得更清楚,我做了一个动画演示,大家感受一下页面搭建的大致原理:动画演示—在线播放—优酷网

布局原理的宏观概念

现在要讲的是两个更宏观的概念:流式布局与弹性布局。我们前面有提到常规布局,那个概念与这两者不能相提并论。其实这两种布局都是基于前面提到的原理实现的,只是区别在于对待自适应问题上采取了不同的策略。

1. 流式布局;

看上图中的App store界面,在iPhone 7和7 plus上略有不同。虽然布局形式类似,但7上面只能看到一张banner,而7 plus则能看到左右两边banner露出来。而且App展示区域里,7上能看到3列多一点,7 plus则能看到4列多。屏幕大则视野更大,能显示更多内容,这是流式布局的思想。

2. 弹性布局;

弹性布局则是另一种思路。根据屏幕尺寸变化,让界面上所有元素等比例放大缩小。所以无论在什么尺寸的设备上,看到的画面都是一样的,信息容量相同。只是到了大屏幕上,会变得像老年手机那样硕大无比。

这两种自适应方式都有各自的用途,不能说哪种一定更好。但我们在设计时可以考虑一下这个问题,什么类型的设计适合哪种布局。

设计组件化

补完了基础知识,现在就可以讲组件化设计的具体方法了,设计师如何运用组件化思维?

一、提取产品中的共用部分;

首先要提取产品中的共用部分。我列举了一些,这些都是极为常见的组件。

1. 导航

2. 按钮

3. 表单

4. Tab

5. 翻页

这个翻页其实是有点问题的,少了个当前选中状态,不知道现在是第几页啊。所以说组件的提取要考虑周全,所有可能的状态都要设计。

6. 表格

7. 进度条

8. 弹窗、列表、错误提示……等等,还有很多。这些都是我前面说的经过实践验证的设计模式,是久经考验的展现与交互方式,完全有理由统一设计,提取成组件。

二、制作成通用组件

找到了这些共用元素,下面到具体制作环节,关于工具的使用我不会讲太多,也没有必要讲,主要是思路与观念。我用Sketch录了3段操作演示,有利于帮助大家理解。

下面这段视频主要是讲,我是如何在实际设计过程中进行组件化的操作。

1. Sketch Symbol;我们把这个列表项提取为一个组件,现在看其实没什么变化。我们先复制几个出来,让它成为一个列表。然后我们到组件页面去,发现刚才提取的组件就在这里。我们尝试把圆形的头像改成方形,嗯,去掉边框。回到列表界面来,发现整个列表的头像都变成方形了,但我们只在组件里做了一次修改,就达到这样的效果。这也就是前面所说的,组件化便于修改设计。

Sketch symbol—在线播放—优酷网

2. Sketch Overrides;下面这段视频是讲如何把组件的样式与内容分离开。

还是刚才的组件,不过我把头像右边代表两行文字的矩形换成了真正的文字,我要把它当作通讯录界面来设计。现在我们回到列表界面,发现列表里每一项都变成了姓名+电话号码。然后我们在每一项的Overrides选项中输入数据,因为这是在组件之外输入的信息,它只会影响那一条内容。用这种方式把每个列表项都填上数据。现在我们再进到组件里,做点样式修改,比如把电话号码颜色改成灰色。回到列表,所有电话号码都变灰了,内容保持不变。这样就实现了样式与内容的分离,降低耦合度对设计同样适用。

Sketch Overrides—在线播放—优酷网

3. Sketch Symbol 的嵌套;下面这段视频是讲组件的嵌套。

组件小的可以只有一个按钮,大的可以是一个交互极其复杂的多步筛选项。所以复杂组件内再嵌入简单组件,这是很常见的事情。

我给刚才的组件又增加了一个按钮,我们把这个按钮也提取成组件,可以看到它出现在了列表项组件的右侧。回到列表界面,每个列表项都有了按钮,我们选中所有列表项,把按钮文字成呼叫。然后右边还有另一个界面,这里也需要一个按钮。我们在此插入之前提取的按钮组件,把按钮文字改为订阅。如此一来,按钮组件就既存在于界面中,也存在于其他组件中。这时候如果想对按钮的样式做点调整,我们再进入按钮组件,改成灰底白字。回到界面中,发现各处按钮都一起变了。

组件化的思想不限于设计工具,虽然Sketch很先进,很利于实现这种工作方式。但PS也有相应的功能,能够以另一种形式实现组件化。所以可以说设计从来都不会被工具所局限。

Sketch Symbol嵌套—在线播放—优酷网

一个组件就是一个完整的产品

设计组件不是把它搬到另一个地方,然后各处集中引用这么简单。开头我们就说过,组件化思维的精髓是独立、完整、自由组合。刚才我们做到了独立,同时也需要做到完整。

把每个组件当做一个独立产品来设计,考虑空状态、极端情况、尺寸变化,尽可能灵活适应各使用场景。

就拿下图按钮来说,我们必须考虑它的各种状态、极端情况、尺寸变化,还有所有附带的交互效果。这才能称之为一个独立完整的组件,满足其他组件对一个按钮的所有要求。除了最标准的默认、按下、禁用状态,还要考虑按钮的尺寸变化,发生服务器交互时每个状态的样式,还有特殊按钮内容的展示效果。

思考组件相互间的组合方式

组件内部完整了,接下来就是自由组合了。但并不是真的那么自由,我们要确定一些常用的组合方式。

1. 统一组件与组件、组件与散件之间的组合方式;

如下图,像这样一个后台管理界面,页面的整体背景色,主菜单与右侧导航的距离,输入框之间的距离……这些也都要有章法,而不是各个页面这些间距都是随心所欲的。

形成规范文档

以上这些工作,沉淀下来,就成了设计规范。这套文档对项目中的其他设计师是莫大的帮助,也是开发人员重要的资料,组件化的规范文档是可以协助开发组件化开发的。

组件化设计是一切的源头,如果我们设计部分的组件化工作做得不到位,自己定的规范自己不遵守,开发同学的组件化工作是无法进行的。

开发组件化

讲完设计组件化,现在我们来讲一下开发的组件化,主要讲的是前端如何运用组件化思维。

1. 按组件,而不是页面来开发;最重要的一点,是需要转变一个观念。我们应该以组件为单位,而不是以页面为单位进行开发。

2. 轻度组件化;

组件化开发有两种不同程度的做法。先讲讲轻度组件化。它的主要思想是同一个组件使用相同的html结构和特定的class名,并且用同一段css代码定义样式,用同一个js函数来定义交互。

如下图,我们来看看下面这个登录框,下面3个代码块是它大致的代码结构。输入框在其他页面肯定也会用到,那么只需要与左边框里的html结构保持一致。各处页面代码中引用同一个css和js文件,至少做到了在一处集中管理样式与交互。但如果组件的html结构发生变化,修改的工作量还是会比较大。

3. 重度组件化;重度组件化的方式可以解决上述说的,如果组件的html结构发生变化,修改的工作量会比较大这个问题。不过这就不仅仅停留在思想层面,对项目的代码结构都有一定的要求。每个组件的html结构、css样式、js交互都独立封装管理,定义好框架和加载方式,内容在加载时从外部填充。

在重度组件化的项目中,每个组件都做到了彻底的独立封装。比如下图,这个页头组件,它的代码存在于独立的目录下,这个目录包含了它的html结构、css样式、js交互、资源图、甚至自测试模块。那么各处页面中要加载页头组件,往往只是一条语句,将数据传入这个已存在的结构中就行了。组件如果要与外部进行数据传递,也应该以接口形式对外开放。组件内部是个黑盒,外部只需要了解数据的输入与返回,不必关心组件内的工作原理。

组件化思维管理开发项目

用这种思路管理项目,也会改变开发的协作方式。大家不再是按页面分工,而是按组件来分工。如下图,页头和tab由一人负责,列表和页脚由另一个人负责,弱化了相互间的依赖关系。直到将组件拼装成页面,才需要处理组件之间相互作用的部分,但这时候工作量已经被大大消化了。

我们可以来感受一下组件化管理的项目,应该是个什么样的结构。

一个应用由大量页面组成,一个页面的绝大部分都是组件。组件内部已经定义好了完整的结构,可以独立运行。纵观整个项目,可能就会是这样一个结构。组件的代码占了大多数,能共用的都尽量共用,各个页面的特殊代码则会变得非常轻。各功能模块的划分清晰明确,一目了然。

重在维护

虽然前面说了这么多好处,但组件化不是一件轻松的工作。在项目初期的准备工作会增加一定工作量,但随着时间推移会发挥出巨大的优势。

想象一下,像windows操作系统这种航母级的开发项目,如果不用组件化的方式来管理,它有可能成为现实吗?

我们设计师要做的,就是要有专人负责维护设计组件库。组件发生了任何设计修改,或者加入了新组件,都要及时反映在设计规范上。

开发同学也需要指定人员来负责维护具体的组件。他们要做的,我就不好多说了,毕竟我不是专业的。

但可以举个例子,像Google Ara项目的这款模块化手机一样:摄像头模块只负责拍照,处理照片得交给运算模块;而GPS模块只负责定位相关功能,导航语音播报则需要发声模块来处理。任何模块的拆换,对其余模块的运转毫无影响。

及时沟通反馈

双方的维护工作固然重要,更重要的是沟通交换信息。有任何变化都要及时告知对方,组件的高度同步,是这种工作方式得以长期延续的关键。

组件化思维

其实组件化思维不仅仅适用于UI设计中,它可以贯穿到所有的设计中,甚至于生活中。

如下图,元旦刷红包html5页面,用的也是组件化思维,把单个元素独立出来,当做一个整体设计,所有的独立组件设计完成后,再像搭积木一样,将其拼接为一个完整的页面。

组件化思维不仅可用于设计中,还有生活中。它的精髓其实就这么3点:独立、完整、自由组合。而我们生活中见到的绝大多数工业产品,就是这么造出来的,比如汽车工业,比如富士康的iPhone生产线。甚至部队的编制也是遵循这个原理。

最后,我想给大家看一段1分钟的视频。这是宜家厨房的宣传片,宜家是一家高度推崇组件化的公司。不仅仅是用在生产流程中,也把组件化思维从幕后推向了台前,成为了自己品牌的一种语言。我们来直观感受一下,让组件化的思想在你脑海中留下一个具象的画面:宜家厨房—在线播放—优酷网

最后,谢谢看完文章的各位,希望能对各位有所帮助。