組件化其實(shí)是一個(gè)很早就有的概念了,并不多稀奇,也不難理解。尤其是對(duì)于編程開(kāi)發(fā)人員而言,對(duì)此應(yīng)該更是熟悉。而今天這篇文章,我作為一個(gè)UI設(shè)計(jì)師來(lái)談?wù)勎覍?duì)于組件化開(kāi)發(fā)與設(shè)計(jì)的一些想法,從而幫助設(shè)計(jì)師們了解程序員是如何進(jìn)行組件化開(kāi)發(fā)的,怎樣的設(shè)計(jì)才能更好的方便程序員快速落地實(shí)現(xiàn),你又應(yīng)該提供哪些設(shè)計(jì)文件,協(xié)助程序員組件化開(kāi)發(fā)。難道只是效果圖和切圖嗎?肯定不是。
什么是組件化?
組件化在我的理解來(lái)看,有點(diǎn)類(lèi)似于搭積木,如上圖所示,每一塊積木就是一個(gè)組件,是既獨(dú)立又統(tǒng)一的。因?yàn)楠?dú)立,所以它可以自由組合,也可以隨意替換和刪除其中一個(gè)組件,并不會(huì)影響整體。但是它又統(tǒng)一于整體,比如上面的積木都是六邊形的,你不可能拿一個(gè)三角形放進(jìn)去啊。而組件化就是說(shuō),一個(gè)整體項(xiàng)目就是由無(wú)數(shù)個(gè)獨(dú)立的組件搭建起來(lái)的。組件化的工作方式信奉獨(dú)立、完整、自由組合。目標(biāo)就是盡可能把設(shè)計(jì)與開(kāi)發(fā)中的元素獨(dú)立化,使它具備完整的局部功能,通過(guò)自由組合來(lái)構(gòu)成整個(gè)產(chǎn)品。
設(shè)計(jì)師為什么也要有組件化思維呢?
我先來(lái)說(shuō)說(shuō),組件化對(duì)設(shè)計(jì)師有什么好處?
1. 符合產(chǎn)品功能邏輯;作為一個(gè)UI設(shè)計(jì)師,設(shè)計(jì)最重要的一點(diǎn)就是要符合產(chǎn)品功能邏輯,絕不是所謂的“好看”。而組件化的設(shè)計(jì)理念恰恰是最能幫助設(shè)計(jì)符合產(chǎn)品功能邏輯的。
從實(shí)踐驗(yàn)證來(lái)講,特定類(lèi)型的信息,就有特定的最優(yōu)展現(xiàn)方式和交互方式,這叫做設(shè)計(jì)模式。設(shè)計(jì)模式就應(yīng)該提取出來(lái)作為組件。比如要從多個(gè)維度快速檢索和對(duì)比大量數(shù)據(jù),沒(méi)有什么能比表格形式效率更高。想象一下,下面這個(gè)界面的表格數(shù)據(jù),做成卡片式堆疊在一起,劃一張換一條。或者像淘寶商品列表那樣,一行4列平鋪開(kāi)。那還對(duì)比個(gè)P啊,用戶(hù)都要摔鼠標(biāo)了。
2. 有助于保持交互一致性;比如說(shuō),在一個(gè)項(xiàng)目里,選擇日期應(yīng)該是統(tǒng)一的交互方式,在整個(gè)產(chǎn)品中就應(yīng)該只有一種存在形式。所以時(shí)間選擇器就是一個(gè)組件,一個(gè)可以復(fù)用的組件。如果你沒(méi)有組件化思維,很可能出現(xiàn)好幾個(gè)不同的時(shí)間選擇器,一會(huì)兒是滾輪撥盤(pán),一會(huì)兒是日歷,一會(huì)兒又是下拉列表,這樣的設(shè)計(jì)絕對(duì)是不能上線的。當(dāng)然,該統(tǒng)一的地方還有很多,比如:錯(cuò)誤提示的形式,進(jìn)度條的交互方式,導(dǎo)航欄和按鈕的樣式,表單,下拉菜單等等。
3. 保持視覺(jué)風(fēng)格的統(tǒng)一;這部分主要是視覺(jué)方面的考慮,更多樣式上的差異,不同的樣式會(huì)給產(chǎn)品帶來(lái)不同的調(diào)性。
就拿下圖按鈕來(lái)說(shuō)。圓頭造型表現(xiàn)出一種柔和親切的特質(zhì),同時(shí)有利于將注意力聚焦到其中內(nèi)容上。而直角則展現(xiàn)出一種棱角分明的硬朗,邊界更加清晰。想一想三星手機(jī)和錘子手機(jī)的外觀造型,兩種截然不同的感覺(jué)。為了保持產(chǎn)品視覺(jué)風(fēng)格統(tǒng)一,設(shè)計(jì)師應(yīng)該找到最合適的方案,并處處保持統(tǒng)一,不可以太隨心所欲。比如說(shuō),在類(lèi)似的界面中,有的按鈕是方的,有的按鈕卻是圓的,這怎么能行呢?甚至于同一產(chǎn)品中,不同界面的下拉菜單樣式都不一樣,這也絕對(duì)是不行的。
4. 便于多設(shè)計(jì)師協(xié)作;組件化設(shè)計(jì)是大型設(shè)計(jì)項(xiàng)目的必要條件。
比如兩位設(shè)計(jì)師協(xié)作,一個(gè)在設(shè)計(jì)注冊(cè)界面,一個(gè)在設(shè)計(jì)修改密碼界面,或者在設(shè)計(jì)某個(gè)問(wèn)卷調(diào)查的彈窗。這其中都有表單,兩個(gè)人設(shè)計(jì)出來(lái)不一樣怎么辦?一個(gè)邊框顏色深一點(diǎn),一個(gè)邊框顏色淺一點(diǎn)?表單的點(diǎn)擊反饋效果一個(gè)是黑色表示觸發(fā)輸入,一個(gè)是主色表示觸發(fā)輸入?其實(shí)沒(méi)理由不同,應(yīng)該保持一致??陬^約定太麻煩,而且難以保證執(zhí)行到位,組件化就是最好的解決方式。
5. 便于修改設(shè)計(jì);設(shè)計(jì)總是需要修改優(yōu)化的,有些改動(dòng)牽扯全局,動(dòng)靜非常大。
比如管理后臺(tái)的界面,左側(cè)的主導(dǎo)航是全站通用的。某天決定要給它換一套淺色的設(shè)計(jì),難道每個(gè)源文件都改一遍嗎?如果產(chǎn)品邏輯復(fù)雜,源文件有上百個(gè)呢?你準(zhǔn)備一個(gè)個(gè)的改到什么時(shí)候呢?3天?5天?甚至幾個(gè)禮拜,時(shí)間就會(huì)都花在這種無(wú)意義的重復(fù)勞動(dòng)上了。但是如果你一開(kāi)始就依照組件化設(shè)計(jì),那么對(duì)于設(shè)計(jì)的修改就會(huì)是非常方便的,你只需要將主導(dǎo)航這一個(gè)組件改為淺色即可。改這么一個(gè)組件的顏色,你甚至一分鐘都不用就搞定了。剩下的時(shí)間,可以用來(lái)干嘛呢?用來(lái)構(gòu)思思考設(shè)計(jì)樣式,交互方式,優(yōu)化你的設(shè)計(jì),這才是設(shè)計(jì)師應(yīng)該做的。
開(kāi)發(fā)人員為什么也要有組件化思維呢?
下面講講組件化對(duì)開(kāi)發(fā)的意義。其實(shí)開(kāi)發(fā)同學(xué)從中受益會(huì)比設(shè)計(jì)師更多。因?yàn)榻M件化開(kāi)發(fā)絕對(duì)可以大大提高工作效率,減少加班時(shí)間的。不加班了,開(kāi)發(fā)同學(xué)們,你們終于可以打游戲泡妞出去浪啦。
1. 降低耦合度;降低耦合度,相信這是大型項(xiàng)目都在追求的。
舉個(gè)例子,如果要把頁(yè)面的body區(qū)域加寬。內(nèi)部許多元素因?yàn)楦?dòng)、固定寬度、百分比寬度、文字行數(shù)減少等等,布局會(huì)亂套。就像下圖里這樣,這是因?yàn)閮?nèi)部模塊的樣式對(duì)頁(yè)面父級(jí)元素存在依賴(lài)和繼承。
可能有人會(huì)覺(jué)得并不存在依賴(lài)關(guān)系,但其實(shí)固定寬度本身就是一種依賴(lài)關(guān)系。假如說(shuō)頁(yè)面主體部分寬度1000px,左側(cè)邊欄200px,右側(cè)800px。沒(méi)錯(cuò),這是按設(shè)計(jì)圖來(lái)做的。那這個(gè)800px寬是怎么得出的?正是因?yàn)轫?yè)面主體寬度1000px,才找了個(gè)合適的左右比例,設(shè)計(jì)成這樣的。所以無(wú)可避免,從設(shè)計(jì)這個(gè)環(huán)節(jié)開(kāi)始就產(chǎn)生了依賴(lài)關(guān)系。像這種情況,我寧可在模塊外面多套一層容器,模塊本身的寬度寫(xiě)成100%,外面那層容器屬于框架布局,具體寬度寫(xiě)在它上面。雖然DOM樹(shù)變復(fù)雜了,但內(nèi)外的布局邏輯被分離了。
2. 減少冗余;頁(yè)面中所有<table>標(biāo)簽,都可以使用同一套css,不必每個(gè)頁(yè)面單獨(dú)定義。
比方說(shuō)要新增一個(gè)帶表格的界面,開(kāi)發(fā)同學(xué)按照設(shè)計(jì)的效果圖一行行寫(xiě)頁(yè)面。但是如果在某個(gè)已有界面中就存在表格?或許當(dāng)時(shí)是另一位開(kāi)發(fā)同學(xué)做的。相比重新寫(xiě)一遍,把代碼要過(guò)來(lái)直接用更方便一點(diǎn)吧?如果表格樣式之后又要改呢,是不是兩個(gè)地方都得改。如此一來(lái),用到表格的頁(yè)面越多,就越容易漏改。而且靜態(tài)資源服務(wù)器上存了太多份關(guān)于表格的樣式,其中內(nèi)容明明是一樣,這就會(huì)導(dǎo)致代碼越來(lái)越冗余。
3. 優(yōu)化性能;優(yōu)化性能剛好可以接著上一條說(shuō)。那么多份表格的樣式,客戶(hù)端每打開(kāi)一個(gè)新的表格頁(yè)面,就得加載一次。占用帶寬,浪費(fèi)了緩存資源。雖然一兩個(gè)的影響幾乎感受不到,但這種情況一多,就會(huì)對(duì)用戶(hù)體驗(yàn)產(chǎn)生明顯的影響。慢,是用戶(hù)體驗(yàn)的頭等大忌,沒(méi)有之一。應(yīng)該是按需加載資源,一個(gè)簡(jiǎn)單的登錄頁(yè)面,沒(méi)有必要加載整站的css與js代碼,拖慢速度。
4. 便于多開(kāi)發(fā)協(xié)作;這和設(shè)計(jì)師協(xié)作的道理相同。如果兩個(gè)開(kāi)發(fā)同學(xué)都在制作帶有下拉菜單的頁(yè)面,這部分工作只要交給其中一人就行了。TA做好之后封裝成組件,另一位開(kāi)發(fā)在自己的頁(yè)面中加載就行了。
5. 便于查錯(cuò);這便于查錯(cuò),是耦合性降低的一個(gè)副產(chǎn)品。它可以大大加快錯(cuò)誤排查的速度。如果頁(yè)面上出現(xiàn)問(wèn)題,可以找出每個(gè)可能有關(guān)的組件,逐個(gè)拔除,直到恢復(fù)正常。這樣就能迅速鎖定錯(cuò)誤發(fā)生的位置。同時(shí)組件內(nèi)也可以形成完整的自測(cè)單元,也方便了測(cè)試工作。
如下圖,突然出現(xiàn)某個(gè)彈窗樣式錯(cuò)亂。如果采用組件化開(kāi)發(fā),只要檢查彈窗這個(gè)組件的代碼,如果是這部分代碼出現(xiàn)問(wèn)題了,只需要解決這部分代碼就行了,如果彈窗組件沒(méi)有問(wèn)題,則說(shuō)明不是彈窗代碼導(dǎo)致的bug,不需要解決彈窗,而是去排查別處的代碼,這樣就能大大縮小排查范圍。
6. 便于修改;假如設(shè)計(jì)師每個(gè)頁(yè)面改同一個(gè)地方要花一個(gè)小時(shí),那開(kāi)發(fā)做同樣的事情至少要花一個(gè)上午,至少!封裝成組件,可以把這個(gè)時(shí)間縮短到10分鐘。畢竟不用去改幾十個(gè)頁(yè)面的HTML、CSS和JS,改一個(gè)組件就可以了。比方說(shuō),來(lái)了一個(gè)新需求,要求所有頁(yè)面的標(biāo)題字號(hào)都要加大,開(kāi)發(fā)同學(xué)如果不按照組件化開(kāi)發(fā),那就要一個(gè)個(gè)頁(yè)面的改了。我想這就是別的開(kāi)發(fā)可以出去浪,而你卻要不停地加班的原因之一吧。
設(shè)計(jì)師要懂的頁(yè)面布局原理
講了組件化的意義,本來(lái)順理成章應(yīng)該講組件化的具體做法。但在這之前其實(shí)有必要插入這一塊內(nèi)容,幫助沒(méi)有前端基礎(chǔ)的設(shè)計(jì)師了解,開(kāi)發(fā)是如何把頁(yè)面搭建起來(lái)的。大家可以先有一個(gè)粗略的想象,就像是重力朝上的俄羅斯方塊。頁(yè)面元素都是從下往上這樣一行一行搭出來(lái)的,不過(guò)這個(gè)玩家有強(qiáng)迫癥,他一定會(huì)從左上角、右上角或者中間位置搭起。當(dāng)然……搭滿(mǎn)一行并不會(huì)消除。 ¯/_( ツ )_/¯
布局原理:
1. 行內(nèi)元素與塊元素;這網(wǎng)頁(yè)布局中有兩個(gè)概念:行內(nèi)元素和塊元素。它們是非此即彼的關(guān)系,網(wǎng)頁(yè)里只要是你能看見(jiàn)的東西,一定不是行內(nèi)元素就是塊元素。
這兩種元素的表現(xiàn)略有不同。圖中虛線框代表一行,但實(shí)際上這是不可見(jiàn)的,只是我為了說(shuō)明布局方式畫(huà)出來(lái)的,其中的綠色矩形才是頁(yè)面上真實(shí)可見(jiàn)的元素。
如上圖,我們看第一行,這里有3個(gè)行內(nèi)元素。內(nèi)容長(zhǎng)度不同,它們表現(xiàn)出來(lái)的寬度就不同,這是一種會(huì)隨內(nèi)容變化而改變尺寸的布局單元,而且它們總是從左到右橫向排列,只要一行里排得下。再看第二行,這里只有1個(gè)塊元素。你看它內(nèi)容很短,就三個(gè)字,卻占了一整行。沒(méi)錯(cuò),塊元素就是這么任性。就像自習(xí)室一卷廁紙占一排座位那樣。最后看第三行。淺綠色是一個(gè)塊元素,深綠色是它內(nèi)部的元素。所以元素之間是可以嵌套的,無(wú)論多么復(fù)雜的頁(yè)面,都是這樣一層層嵌套形成的。但是要注意,塊元素內(nèi)可以嵌入行內(nèi)元素和塊元素,行內(nèi)元素只能嵌入行內(nèi)元素。請(qǐng)看其中的深綠色部分,第二行是一個(gè)塊元素,設(shè)定了寬度,并且居中排列。其實(shí)前兩個(gè)行內(nèi)元素的右邊明明有空間,而且右邊還放得下一個(gè)行內(nèi)元素。但即使如此,它還是要占一整行。當(dāng)然,塊元素這個(gè)獨(dú)占一行的特性有例外,我們接下來(lái)就會(huì)說(shuō)。
2. 浮動(dòng);剛才講的是常規(guī)的布局方式,我們現(xiàn)在講兩種打破常規(guī)的方式。
如下圖所示,浮動(dòng)有兩個(gè)方向,向左和向右。被加上了浮動(dòng)屬性的元素,表現(xiàn)都會(huì)變得類(lèi)似于行內(nèi)元素,根據(jù)內(nèi)容變化尺寸。第一行的左右浮動(dòng)元素都可以是塊元素,但它們卻排在了一行里。第二行和第三行是一組對(duì)比,表現(xiàn)了非浮動(dòng)元素與浮動(dòng)元素混合排列時(shí)的規(guī)則。第二行的文字是一個(gè)常規(guī)布局的元素,可以看到左右浮動(dòng)的元素各就各位,常規(guī)布局的文字很靈活地填充空隙,就像報(bào)紙排版一樣。而第三行里的情況,文字段落也加上左浮動(dòng)屬性,并且限定寬度,它就會(huì)跟在左浮動(dòng)元素的右側(cè)。當(dāng)然,如果文字不限定寬度,它還是會(huì)獨(dú)占一行,因?yàn)槲淖肿銐蚨唷_@和塊元素獨(dú)占一行的道理不同,它仍然帶有浮動(dòng)屬性,本應(yīng)該跟在左浮動(dòng)元素的右邊。只是因?yàn)樽陨韺挾忍螅恍袛D不下了。
3. 絕對(duì)定位;另一種打破常規(guī)的布局方式是絕對(duì)定位。
這就毫無(wú)章法可言了,像狗皮膏藥一樣想貼哪里貼哪里,還可以像下圖里這樣層疊著貼??傊?,絕對(duì)定位的元素不會(huì)占據(jù)常規(guī)布局和浮動(dòng)布局中的任何空間,而是直接擋住它背后的內(nèi)容。不過(guò)既然可以層疊,就有誰(shuí)在前誰(shuí)在后的問(wèn)題。這和設(shè)計(jì)工具里的圖層是一樣的,當(dāng)然有辦法可以控制。
一個(gè)頁(yè)面是如何搭建出來(lái)的?
為了讓大家看得更清楚,我做了一個(gè)動(dòng)畫(huà)演示,大家感受一下頁(yè)面搭建的大致原理:動(dòng)畫(huà)演示—在線播放—優(yōu)酷網(wǎng)
布局原理的宏觀概念
現(xiàn)在要講的是兩個(gè)更宏觀的概念:流式布局與彈性布局。我們前面有提到常規(guī)布局,那個(gè)概念與這兩者不能相提并論。其實(shí)這兩種布局都是基于前面提到的原理實(shí)現(xiàn)的,只是區(qū)別在于對(duì)待自適應(yīng)問(wèn)題上采取了不同的策略。
1. 流式布局;
看上圖中的App store界面,在iPhone 7和7 plus上略有不同。雖然布局形式類(lèi)似,但7上面只能看到一張banner,而7 plus則能看到左右兩邊banner露出來(lái)。而且App展示區(qū)域里,7上能看到3列多一點(diǎn),7 plus則能看到4列多。屏幕大則視野更大,能顯示更多內(nèi)容,這是流式布局的思想。
2. 彈性布局;
彈性布局則是另一種思路。根據(jù)屏幕尺寸變化,讓界面上所有元素等比例放大縮小。所以無(wú)論在什么尺寸的設(shè)備上,看到的畫(huà)面都是一樣的,信息容量相同。只是到了大屏幕上,會(huì)變得像老年手機(jī)那樣碩大無(wú)比。
這兩種自適應(yīng)方式都有各自的用途,不能說(shuō)哪種一定更好。但我們?cè)谠O(shè)計(jì)時(shí)可以考慮一下這個(gè)問(wèn)題,什么類(lèi)型的設(shè)計(jì)適合哪種布局。
設(shè)計(jì)組件化
補(bǔ)完了基礎(chǔ)知識(shí),現(xiàn)在就可以講組件化設(shè)計(jì)的具體方法了,設(shè)計(jì)師如何運(yùn)用組件化思維?
新聞熱點(diǎn)
疑難解答