一種靈活可靠的工作方式:組件化設計與開發
終于迎來一期特刊。最近打算在公司內部做一個分享,講的是組件化的設計與開發的思維方式。準備完演講資料,發現這完全可以改成一篇文章。藏著掖著不合適,發出來分享給有需求的朋友吧,就當是個試講了,希望大家幫忙指出錯誤。
由于本文首先是以keynote的形式誕生的,其中還有動畫和視頻,所以我比較推薦大家直接下載keynote文件(也存了PPT版本)。內容和本文是一樣的,但有些邏輯關系還真得讓畫面動起來才說得清。提醒一下,keynote文件大小將近150mb,嫌麻煩的朋友,當然也歡迎繼續閱讀。(下載地址)
組件化
組件化的工作方式信奉獨立、完整、自由組合。目標就是盡可能把設計與開發中的元素獨立化,使它具備完整的局部功能,通過自由組合來構成整個產品。
對于計算機這么復雜的工業產品,組件化是唯一能使它成為現實的方法。我中學暑假去電腦城打工,跟著別人學習電腦維修。CPU在哪里,負責什么,如何拆裝;內存在哪里,負責什么,如何拆裝。這些都是基礎知識,各部分各司其職,什么壞了就換什么。我還見過資深維修工修主板,他真的能找出主板上哪個電容爆了,換一個相同規格的上去,電腦又能正常開機了。
對產品設計的意義
當然今天我們不講電腦維修,組件化思維要運用到我們的工作中。首先要了解,它對設計和開發到底有什么意義?
這部分雖然講的是設計,但對開發同學也有價值。你們能了解設計師在做設計時的思路,說直白點就是摸清楚我們的套路。其實我們做設計的時候會有系統的考慮,并不是天馬行空,想一出是一出。
(1)符合功能邏輯
組件化的設計恰恰是符合產品功能邏輯的。特定類型的信息,就有特定的最優展現方式和交互方式,這叫做設計模式。設計模式就應該提取出來作為組件。
比如要從多個維度快速檢索和對比大量數據,沒有什么能比表格形式效率更高。想象一下,上面這個界面的表格數據,做成卡片式堆疊在一起,劃一張換一條,或者像淘寶商品列表那樣,一行4列平鋪開。那還對比個P啊,用戶都要摔鼠標了。
(2)保持交互一致性
交互的一致性,或者說可預測性,是用戶體驗的根本。比如日期選擇組件,在整個產品中就應該只有一種存在形式。如果一會兒是滾輪撥盤,一會兒是日歷,一會兒又是下拉列表,這樣的設計絕對是不能上線的。
(3)保持視覺風格統一
這部分主要是視覺方面的考慮,更多樣式上的差異。不同的樣式會給產品帶來不同的調性。
就拿按鈕來說。圓頭造型表現出一種柔和親切的特質,同時有利于將注意力聚焦到其中內容上。而直角則展現出一種棱角分明的硬朗,邊界更加清晰。想一想三星手機和錘子手機的外觀造型,兩種截然不同的感覺。
為了保持產品視覺風格統一,設計師應該找到最合適的方案,并處處保持統一,不可以太隨心所欲。
(4)便于多設計師協作
組件化設計是大型設計項目的必要條件。比如兩位設計師協作,一個在設計注冊界面,一個在設計修改密碼界面,或者在設計某個問卷調查的彈窗。這其中都有表單,兩個人設計出來不一樣怎么辦?一個邊框顏色深一點,一個邊框顏色淺一點?其實沒理由不同,應該保持一致。口頭約定太麻煩,而且難以保證執行到位,組件化是最好的解決方式。
(5)便于修改設計
設計總是要修改優化的,有些改動牽扯全局,動靜非常大。
比如管理后臺的界面,左側的主導航是全站通用的。某天決定要給它換一套淺色的設計,難道每個PSD都改一遍嗎?如果產品邏輯復雜,PSD有上百個呢?
對開發的意義
下面講講組件化對開發的意義。其實開發同學從中受益比設計師更多。
(1)降低耦合度
降低耦合度,相信這是大型項目都在追求的。
舉個例子,如果要把頁面的body區域加寬。內部許多元素因為浮動、固定寬度、百分比寬度、文字行數減少等等,布局會亂套。就像這圖里這樣,這是因為內部模塊的樣式對頁面父級元素存在依賴和繼承。
可能有人會覺得并不存在依賴關系,但其實固定寬度本身就是一種依賴關系。假如說頁面主體部分寬度1000px,左側邊欄200px,右側800px。沒錯,這是按設計圖來做的。那這個800px寬是怎么得出的?正是因為頁面主體寬度1000px,才找了個合適的左右比例,設計成這樣的。所以無可避免,從設計這個環節開始就產生了依賴關系。
像這種情況,我寧可在模塊外面多套一層容器,模塊本身的寬度寫成100%,外面那層容器屬于框架布局,具體寬度寫在它上面。雖然DOM樹變復雜了,但內外的布局邏輯被分離了。
(2)減少冗余
比方說要新增一個帶表格的界面,開發同學按照設計的效果圖一行行寫頁面。但是如果在某個已有界面中就存在表格?或許當時是另一位開發同學做的。相比重新寫一遍,把代碼要過來直接用更方便一點吧?
如果表格樣式之后又要改呢,是不是兩個地方都得改。如此一來,用到表格的頁面越多,就越容易漏改。而且靜態資源服務器上存了太多份關于表格的樣式,其中內容明明是一樣的。
(3)優化性能
優化性能剛好可以接著上一條說。
那么多份表格的樣式,客戶端每打開一個新的表格頁面,就得加載一次。占用帶寬,浪費了緩存資源。雖然一兩個的影響幾乎感受不到,但這種情況一多,就會對用戶體驗產生明顯的影響。
慢,是用戶體驗的頭等大忌,沒有之一。
(4)便于多開發協作
這和設計師協作的道理相同。
如果兩個開發同學都在制作帶有下拉菜單的頁面,這部分工作只要交給其中一人就行了。TA做好之后封裝成組件,另一位開發在自己的頁面中加載就行了。
(5)便于查錯
便于查錯,是耦合性降低的一個副產品。它可以大大加快錯誤排查的速度。
如果頁面上出現問題,可以找出每個可能有關的組件,逐個拔除,直到恢復正常。這樣就能迅速鎖定錯誤發生的位置。同時組件內也可以形成完整的自測單元,也方便了測試工作。
(6)便于修改
假如設計師每個頁面改同一個地方要花一個小時,那開發做同樣的事情至少要花一個上午,至少。
封裝成組件,可以把這個時間縮短到10分鐘。畢竟不用去改幾十個頁面的HTML、CSS和JS,改一個組件就可以了。
布局原理
講了組件化的意義,本來順理成章應該講組件化的具體做法。但在這之前其實有必要插入這一塊內容,幫助沒有前端基礎的設計師了解,開發是如何把頁面搭建起來的。
大家可以先有一個粗略的想象,就像是重力朝上的俄羅斯方塊。頁面元素都是從下往上這樣一行一行搭出來的,不過這個玩家有強迫癥,他一定會從左上角、右上角或者中間位置搭起。當然……搭滿一行并不會消除。
行內元素與塊元素
網頁布局中有兩個概念:行內元素和塊元素。它們是非此即彼的關系,網頁里只要是你能看見的東西,一定不是行內元素就是塊元素。
這兩種元素的表現略有不同。虛線框代表一行,但實際上這是不可見的,只是我為了說明布局方式畫出來的,其中的綠色矩形才是頁面上真實可見的元素。
我們看第一行,這里有3個行內元素。內容長度不同,它們表現出來的寬度就不同,這是一種會隨內容變化而改變尺寸的布局單元,而且它們總是從左到右橫向排列,只要一行里排得下。
再看第二行,這里只有1個塊元素。你看它內容很短,就三個字,卻占了一整行。沒錯,塊元素就是這么任性。自習室一卷廁紙占一排座位。
最后看第三行。淺綠色是一個塊元素,深綠色是它內部的元素。所以元素之間是可以嵌套的,無論多么復雜的頁面,都是這樣一層層嵌套形成的。但是要注意,塊元素內可以嵌入行內元素和塊元素,行內元素只能嵌入行內元素。請看其中的深綠色部分,第二行是一個塊元素,設定了寬度,并且居中排列。其實前兩個行內元素的右邊明明有空間,而且右邊還放得下一個行內元素。但即使如此,它還是要占一整行。
當然,塊元素這個獨占一行的特性有例外,我們接下來就會說。
浮動
剛才講的是常規的布局方式,我們現在講兩種打破常規的方式。
浮動有兩個方向,向左和向右。被加上了浮動屬性的元素,表現都會變得類似于行內元素,根據內容變化尺寸。第一行的左右浮動元素都可以是塊元素,但它們卻排在了一行里。
第二行和第三行是一組對比,表現了非浮動元素與浮動元素混合排列時的規則。第二行的文字是一個常規布局的元素,可以看到左右浮動的元素各就各位,常規布局的文字很靈活地填充空隙,就像報紙排版一樣。而第三行里的情況,文字段落也加上左浮動屬性,并且限定寬度,它就會跟在左浮動元素的右側。
當然,如果文字不限定寬度,它還是會獨占一行,因為文字足夠多。這和塊元素獨占一行的道理不同,它仍然帶有浮動屬性,本應該跟在左浮動元素的右邊。只是因為自身寬度太大,一行擠不下了。
絕對定位
另一種打破常規的布局方式是絕對定位。這就毫無章法可言了,像狗皮膏藥一樣想貼哪里貼哪里,還可以像圖里這樣層疊著貼??傊?,絕對定位的元素不會占據常規布局和浮動布局中的任何空間,而是直接擋住它背后的內容。
不過,既然可以層疊,就有誰在前誰在后的問題。這和設計工具里的圖層是一樣的,當然有辦法可以控制。
一個頁面是如何搭建出來的
我做了一個動畫演示,大家感受一下頁面搭建的大致原理。(點擊查看)
流式布局
現在要講的是兩個更宏觀的概念:流式布局與彈性布局。
我們前面有提到常規布局,那個概念與這兩者不能相提并論。其實這兩種布局都是基于前面提到的原理實現的,只是區別在于對待自適應問題上采取了不同的策略。
看圖中的App store界面,在iPhone 7和7 plus上略有不同。雖然布局形式類似,但7上面只能看到一張banner,而7 plus則能看到左右兩邊banner露出來。而且App展示區域里,7上能看到3列多一點,7 plus則能看到4列多。屏幕大則視野更大,能顯示更多內容,這是流式布局的思想。
彈性布局
彈性布局則是另一種思路。根據屏幕尺寸變化,讓界面上所有元素等比例放大縮小。所以無論在什么尺寸的設備上,看到的畫面都是一樣的,信息容量相同。只是到了大屏幕上,會變得像老年手機那樣碩大無比。
這兩種自適應方式都有各自的用途,不能說哪種一定更好。但我們在設計時可以考慮一下這個問題,什么類型的設計適合哪種布局。
組件化設計
補完了基礎知識,現在就可以講組件化設計的具體方法了。
提取產品中的共用部分
首先要提取產品中的共用部分。我列舉了一些,這些都是極為常見的組件。
這個翻頁其實有點問題,少了個當前選中狀態,不知道現在是第幾頁啊。所以說組件的提取要考慮周全,所有可能的狀態都要設計。
制作成通用組件
找到了這些共用元素,下面到具體制作環節,關于工具的使用我不會講太多,主要是思路與觀念。我用Sketch錄了3段操作演示,我們邊看邊講。
(1)Sketch Symbol
這段視頻是講Sketch中組件的使用。(點擊查看)
我們把這個列表項提取為一個組件,現在看其實沒什么變化。我們先復制幾個出來,讓它成為一個列表。然后我們到組件頁面去,發現剛才提取的組件就在這里。我們嘗試把圓形的頭像改成方形,嗯,去掉邊框?;氐搅斜斫缑鎭恚l現整個列表的頭像都變成方形了,但我們只在組件里做了一次修改,就達到這樣的效果。
(2)Sketch Overrides
這段視頻是講如何把組件的樣式與內容分離開。(點擊查看)
還是剛才的組件,不過我把頭像右邊代表兩行文字的矩形換成了真正的文字,我要把它當作通訊錄界面來設計?,F在我們回到列表界面,發現列表里每一項都變成了姓名+電話號碼。然后我們在每一項的Overrides選項中輸入數據,因為這是在組件之外輸入的信息,它只會影響那一條內容。用這種方式把每個列表項都填上數據。現在我們再進到組件里,做點樣式修改,比如把電話號碼顏色改成灰色?;氐搅斜?,所有電話號碼都變灰了,內容保持不變。
這樣就實現了樣式與內容的分離,降低耦合度對設計同樣適用。
(3)Sketch Symbol 的嵌套
這段視頻是講組件的嵌套。(點擊查看)
組件小的可以只有一個按鈕,大的可以是一個交互極其復雜的多步篩選項。所以復雜組件內再嵌入簡單組件,這是很常見的事情。
我給剛才的組件又增加了一個按鈕,我們把這個按鈕也提取成組件,可以看到它出現在了列表項組件的右側?;氐搅斜斫缑妫總€列表項都有了按鈕,我們選中所有列表項,把按鈕文字成呼叫。然后右邊還有另一個界面,這里也需要一個按鈕。我們在此插入之前提取的按鈕組件,把按鈕文字改為訂閱。如此一來,按鈕組件就既存在于界面中,也存在于其他組件中。這時候如果想對按鈕的樣式做點調整,我們再進入按鈕組件,改成灰底白字?;氐浇缑嬷?,發現各處按鈕都一起變了。
組件化的思想不限于設計工具,雖然Sketch很先進,很利于實現這種工作方式。但PS也有相應的功能,能夠以另一種形式實現組件化。
一個組件就是一個完整的產品
設計組件不是把它搬到另一個地方,然后各處集中引用這么簡單。開頭我們就說過,組件化思維的精髓是獨立、完整、自由組合。剛才我們做到了獨立,同時也需要做到完整。
就拿按鈕來說,我們必須考慮它的各種狀態、極端情況、尺寸變化,還有所有附帶的交互效果。這才能稱之為一個獨立完整的組件,滿足其他組件對一個按鈕的所有要求。
除了最標準的默認、按下、禁用狀態,還要考慮按鈕的尺寸變化,發生服務器交互時每個狀態的樣式,還有特殊按鈕內容的展示效果。
思考相互間的組合方式
組件內部完整了,接下來就是自由組合了。但并不是真的那么自由,我們要確定一些常用的組合方式。
像這樣一個后臺管理界面:頁面的整體背景色,主菜單與右側內容的距離,輸入框之間的距離……這些也都要有章法。
形成規范文檔
以上這些工作,沉淀下來,就成了設計規范。這套文檔對項目中的其他設計師是莫大的幫助,也是開發人員重要的資料
組件化設計是一切的源頭,如果我們設計部分的組件化工作做得不到位,自己定的規范自己不遵守,開發的同學的組件化工作是無法進行的。
開發組件化
講完設計組件化,現在我們來講一下開發的組件化。
按組件,而不是頁面來開發
最重要的一點,是需要轉變一個觀念。我們應該以組件為單位,而不是以頁面為單位進行開發。
輕度組件化
組件化開發有兩種不同程度的做法。
先講講輕度組件化。它的主要思想是使用相同的html結構和特定的class名,并且用同一段css代碼定義樣式,用同一個js函數來定義交互。
我們來看看上面這個登錄框,下面3個代碼塊是它大致的代碼結構。輸入框在其他頁面肯定也會用到,那么只需要與左邊框里的html結構保持一致。各處頁面代碼中引用同一個css和js文件,至少做到了在一處集中管理樣式與交互。但如果組件的html結構發生變化,修改的工作量還是會比較大。
重度組件化
重度組件化的方式可以解決這個問題,不過這就不僅僅停留在思想層面,對項目的代碼結構都有一定的要求。
每個組件的html結構、css樣式、js交互都獨立封裝管理,定義好框架和加載方式,內容在加載時從外部填充。
在重度組件化的項目中,每個組件都做到了徹底的獨立封裝。比如這個頁頭組件,它的代碼存在于獨立的目錄下,這個目錄包含了它的html結構、css樣式、js交互、資源圖、甚至自測試模塊。
那么,各處頁面中要加載頁頭組件,往往只是一條語句,將數據傳入這個已存在的結構中就行了。
組件如果要與外部進行數據傳遞,也應該以接口形式對外開放。組件內部是個黑盒,外部只需要了解數據的輸入與返回,不必關心組件內的工作原理。
用這種思路管理項目,也會改變開發的協作方式。大家不再是按頁面分工,而是按組件來分工。頁頭和tab由一人負責,列表和頁腳由另一個人負責,弱化了相互間的依賴關系。直到將組件拼裝成頁面,才需要處理組件之間相互作用的部分,但這時候工作量已經被大大消化了。
我們可以來感受一下組件化管理的項目,應該是個什么樣的結構。(點擊查看)
一個應用由大量頁面組成。一個頁面的絕大部分都是組件。組件內部已經定義好了完整的結構,可以獨立運行??v觀整個項目,可能就會是這樣一個結構。組件的代碼占了大多數,能共用的都盡量共用,各個頁面的特殊代碼則會變得非常輕。各功能模塊的劃分清晰明確,一目了然。
重在維護
雖然前面說了這么多好處,但組件化不是一件輕松的工作。在項目初期的準備工作會增加一定工作量,但隨時間推移會發揮出巨大的優勢。
想象一下,像windows操作系統這種航母級的開發項目,如果不用組件化的方式來管理,它有可能成為現實嗎?
我們設計師要做的,就是要有專人負責維護設計組件庫。組件發生了任何設計修改,或者加入了新組件,都要及時反映在設計規范上。
開發同學也需要指定人員來負責維護具體的組件。他們要做的,我就不好多說了,畢竟我不是專業的。
但可以舉個例子,像Google Ara項目的這款模塊化手機一樣:攝像頭模塊只負責拍照,處理照片得交給運算模塊;而GPS模塊只負責定位相關功能,導航語音播報則需要發聲模塊來處理。任何模塊的拆換,對其余模塊的運轉毫無影響。
雙方的維護工作固然重要,更重要的是溝通交換信息。有任何變化都要及時告知對方,組件的高度同步,是這種工作方式得以長期延續的關鍵。
組件化思維
我們跳出工作的范疇,跳出剛才這些條條框框,單純想一想組件化這種思想。其實它可以用來理解生活的方方面面。
它的精髓就是這么3點:獨立、完整、自由組合。我們生活中見到的絕大多數工業產品,就是這么造出來的,比如汽車工業,比如富士康的iPhone生產線。。
而且,組件化甚至都不算是人類的發明。即使放在自然界,這也是早已存在的模式。想想我們人體多么復雜,絕對不亞于windows操作系統。但除去極少數器官之外,任何部分損壞或缺失,我們都能活下來。這不得不說是組件化的奇跡。
最后,我想給大家看一段1分鐘的視頻(點擊查看)。這是宜家廚房的宣傳片,宜家是一家高度推崇組件化的公司。不僅僅是用在生產流程中,也把組件化思維從幕后推向了臺前,成為了自己品牌的一種語言。
我們來直觀感受一下,讓組件化的思想在你腦海中留下一個具象的畫面。
注:部分資料引自《前端工程——基礎篇》
#專欄作家#
可樂橙,微信公眾號:可樂橙(colachangreen)。人人都是產品經理專欄作家,UI/UX設計師,關注互聯網,關注科技?,F居杭州,與小伙伴們正在創業途中?;蛟S不是一名優秀的設計師,至少是個快樂的設計師。
本文原創發布于人人都是產品經理。未經許可,禁止轉載。
看完文章,貌似組件化是設計和前端的活,產品能做什么呢
正在學組建化相關內容,學習了,感謝!
沒看懂所以然
很棒的文檔 學習
很棒的分享,剛好正在準備研究這塊相關