作者|冰山工作室--沙翼
今天要為大家安利的是冰山工作室出即將推出的前端框架CMUI,本文會抽取框架的一部分進行介紹(佈局,列表,動態輔助),讓你瞭解一下這款框架的強大與便捷,但這只是框架的冰山一角。如果你想了解更加詳細的資訊,可以破解本文底部的二維碼,加入我們的群聊來獲取。
起源
2011左右的時候我開始著手研究響應式網頁設計,並基於less語言設計了一套CSS佈局框架,起初的設計包括12列,15列,16列三種結構,最終確定了12+15差值雙列的結構,並考慮申請相應的專利,意外的是幾個月之後推特釋出了前端界家喻戶曉的bootstrap框架。後來我進入一家建站公司並基於這套樣式框架開發了一個高速建站系統feebless(一款Windows下的應用程式),為了防止以後有新的想法做出來之後沒有推廣而落後於人的情況發生,還在系統上線後對響應式結構申請了對應專利保護(點選瞭解一下),這是現在要為大家介紹的CMUI最早的雛形,值得慶幸的是我在準備這篇文章的時候竟然翻到了9年前的手稿,當你瞭解CMUI之後再後頭看這些手稿的時候你會發現很多當年殘留的影子或者一些思想雛形,包括元件化,非同步元件,高速佈局,組合,繼承等。
14年左右的時候我基於模板引擎封裝了一套UI系統,取名為CMUI,後用VUE重新封裝為元件庫用於我們的專案,在我們的實際使用中發現這套結構的開發效率非常之高,並且能夠精準匹配設計稿,現在我們決定將其重新封裝並開源,希望更多的開發者能夠參與其中。
九年前的手稿
重要說明
真假美猴王
CMUI是框架的簡稱,GitHub上的CMUI並不是本次介紹的框架。
專利保護
CMUI以MIT協議進行開源,你可以隨意使用到你的專案中,但是其內部的部分結構(如佈局系統,組合樣式)依舊受專利保護,如果你需要應用到你的框架並再次釋出,請提前聯絡我們,以免引起對應法律糾紛。
PC端還是移動端
CMUI主要用於移動端,但是樣式部分完全適用於PC端,元件方面PC端使用的元件目前提供的還不全面。
為什麼要自己寫一套元件庫?
雖然目前市面上有非常多的元件庫,其中也有一很多非常優秀的代表,但是存在一些非技術性的問題
糟糕的C端應對方案
你所知的大部分框架大量保留了bootstrap的思想,這一點從柵格系統和按鈕及表單的描述就能看出來,我始終不認為用success表示綠色,用primary代表主色是一個優秀的方案,這種結構的優勢在於開發沒有設計師參與的專案時(如中臺系統)可以達到風格的高度統一併且實現主題變色,但是如果針對C端開發,設計稿千變萬化,尤其是你的設計團隊並不十分嚴格的情況下就會變得非常尷尬。
完善不代表適用
提供了完善的元件系統,小到一個按鈕,大到完善的表單,首先要承認這是非常優秀的設計,但並不是最實用的。因為你可能只需要用到一種樣式上的展示,卻要引入一個完整的元件,當然你可以只引入它的樣式檔案,但是如果你這麼做,你就需要記憶大量的class命名,並且在很多情況下根據你的需要去重寫預設的樣式。比如下面這樣
-
<button type="button" class="xx-button xx-button--text" style="float: right;padding: 3px 0px;"><span>操作按鈕</span></button> 複製程式碼
我一眼就知道你是誰
如果你使用了一套UI框架,在你不進行海量修改的的情況下幾乎一眼就能看出是哪個框架搭建的,就像所有使用bootstrap搭建的網站幾乎都長得差不多。
API是個頭痛的問題
記憶API和使用方式是一件非常麻煩的事情,當你使用一套UI框架進行頁面開發的時候,脫離了官網的DEMO和API文件,你可能寸步難行,當你想實現一個類似的效果的時候,你也許會經常把程式碼來回複製,以防止寫錯。
你只是個使用者而非創造者
如果你使用了一款UI框架,而在這套框架裡沒有提供你所需的UI功能,這就變的非常尷尬,如果你再次封裝,可能你的結構可能和原有的結構完全不搭,甚至完全沒有關係,換句話講,你只是一款工具的使用者,而非基於一款工具的創造者。
拋磚引玉的開始
簡介
現在要為大家介紹的框架名為CMUI,這只是一個簡稱,一共包括三個部分:樣式庫,元件庫,方法庫,每個部分都可以獨立使用,你甚至可以直接把它直接插入你的專案,和你現在所使用的UI庫一起使用。
**樣式庫:**全稱cyan,就是赤橙黃綠青藍紫中你唯一不會的那個英文單詞(這一點非常重要)使用sass對css進行了重新的抽取和封裝,基於這套樣式庫你幾乎可以在不書寫額外的CSS的情況下,僅憑藉樣式組合完成頁面的拆分。更重要的是所有的命名都簡單到令人髮指,以至於在你用過一次之後再也不需要去看API文件。
**元件庫:**得益於樣式庫提供了強大的VIEW層展示,因此我們提供的元件也相對較少,僅在單憑樣式無法解決的問題上提供對應的元件,其目的也是為了降低開發者的門檻
**方法庫:**這裡對常用的WEB功能提供了對應的方法,用於減少你的程式碼量
無圖無真相,秀個logo
Cyan不讓你思考,不讓你寫錯
我們在開發的過程中為模組起名字是一個非常痛苦而費腦的過程。主要包括以下幾個方面:
- 命名中存在不常用的英文單詞,不易理解和閱讀(你一定用過百度翻譯?)
- 模組在經過多次需求修改後名稱已經和實際用途不相符
- 兩個樣式完全相同的模組使用不同的命名,多次編寫樣式,比如一個品牌列表和一個使用者列表在樣式上完全相同,鬼知道你的產品和設計什麼時候會修改,那麼你該如何複用?
- 同一個頁面存在兩個類似的模組時命名混亂,如porductTop productBottom productRecommend productNew
- 為準確描述而使用過長的名稱
- ...
為了解決這一問題,Cyan在命名上做了大量的調研和優化,我們希望我們用到的單詞所有人都能一次理解,所有人都能一次寫對,先來看一下樣式庫預設的的所有關鍵字。
顏色類:red orange yellow green cyan blue purple coffee
調整類:margin padding top left bottom center full
邊框類:border item radius round light shadow pill
尺寸類:big small block
元素類:img form swich btn reverse badge
佈局類:flex ratio list item img scroll container
輔助類:disabled square float pos clearfix overflow delete justify limit fixed
複製程式碼
你看到的這些詞就是CMUI樣式庫整合後的的全部class名稱,其中顏色類和尺寸類是使用者自定義的,你可能很難想象緊靠這些簡單的單詞就能完成一個頁面的拆分,但事實確實如此。
隨手寫個京東
我們先用Cyan的結構來還原一個京東首頁商品列表作為一個小小的DEMO。
<div class="list list-col2 border">
<div class="list-item">
<div class="ratio-container img-container">
<img src="圖片地址" alt="">
</div>
<span class=" reverse red badge square pos-a top10 left10">搶</span>
<div class="padding10">
<span class="text-limit2 fs-13">日本進口FaSoLa 瓷磚貼紙對角貼 美縫地板貼防水耐磨地貼客廳裝飾牆貼自粘 波西風情(12個/張) 大</span>
<div class="flex-container margint10">
<span class="text-delete text-light marginr10">999</span>
<span class="text-red fs-13 right">222</span>
<span class="badge reverse">找相似</span>
</div>
</div>
</div>
<div class="list-item">
<!--此處程式碼和上面的相同-->
</div>
</div>
複製程式碼
輸出效果
描述型樣式庫
在這案例中你可以看到我們沒有使用任何額外的CSS就完成了樣式佈局。使用Cyan樣式庫的一個特點就是你不需要關心你做的是什麼,你只需要將你看到的設計稿用class組合描述出來就可以。從另一個角度來說,當你看到HTML結構的時候,你不需要看頁面就知道最終的效果是什麼樣子,因此我們將Cyan稱為描述型樣式庫。
業務邏輯擴充庫
雖然我認為起名字是個非常麻煩的事情,但是如果你覺得使用class進行描述不是你的風格,一定要使用標識業務的命名,你還可以直接引用我們的擴充庫。
<div class="productList">
<div class="productItem">
<div class="productImg">
<img src="" alt="">
</div>
<span class="productName"></span>
<div class="productInfo">
<span class="info_oldPrice"></span>
<span class="info_newPrice"></span>
<span class="p_find"></span>
</div>
</div>
</div>
複製程式碼
@import cyan/extend;
.productList{
@extend list;
.productItem{@extend list-item;}
.productImg{ @extend ratio-container img-container;}
.productName{@extend text-limit2 fs-13;}
.productInfo{
@extend flex-container margint10;
.info_oldPrice{@extend text-delete text-light marginl10}
.info_newPrice{@extend text-red fs-13 right}
.p_find{@extend badge reverse}
}
}
複製程式碼
真正的開篇
六大布局容器
Cyan提供了6個佈局容器,幾乎可以滿足你所有的佈局需求,一起來看一下
網格容器
類似於bootstrap的柵格系統,同時提供12或15兩種陣列方式。
盒容器
與網格容器唯一的區別是沒有間距。
網格容器和盒容器是由於歷史原因以及今後要在PC端實現實現響應式而保留下來的,在實際的移動端開發中並不常用,當然如果你習慣了使用柵格系統也完全可以使用。
比例容器
在任何寬度內建立任何比例的區域,通常用於製作頭像或商品列表,比如上面的案例,視窗寬度不固定,兩列之間的的間距甚至列數設計隨時有可能調整,使用的圖片不一定是正方形,還要保證圖片以某種比例(通常是一比一)進行展現,此時你會用到比例容器。
為了方便你理解,我們先用網格系統來建立列,後面會有更好的方式
<div class="container">
<div class="row">
<div class="span6 margint20"> 先不用關心這個margint20是幹什麼用的,雖然你能猜出來
<div class="ratio-container">此處新增比例容器,內部節點預設會以1:1進行展示
<img src=""/>
</div>
</div>
</div>
</div>
複製程式碼
輸出效果
你可以看到在無論可視區寬度是多少,圖片均已固定比例展示,如果你需要其他的比例尺寸,直接在後面標識出來就可以了
<div class="ratio-container" ratio="2:3">
這裡的節點會以2:3的比例展示
</div>
複製程式碼
比例容器的作用不光如此,他還可以實現非常多的效果,比如下面這樣,你能想到怎麼做嗎?我們後面再說
圖片容器
直接將圖片放入比例容器會產生一個問題,就是如果使用的圖片不是對應比例的,會被拉伸變形,這一定不是你想要的,因此我們需要圖片容器。只需要新增幾個額外的class他就能支援非常多的效果,可以滿足你的各種需要,
<div class="img-container">
<img src=""/> 圖片預設顯示在容器居中的位置
</div>
<div class="img-container round">
<img src=""/> 圖片將以圓形顯示
</div>
複製程式碼
為了方便你理解案例中使用了不同數字來標識位置,選項中藍色的字就是你可以額外新增的class,而且可以隨意組合,你能用到的所有圖片展示效果都可以組裝出來。
滾動容器
想建立一個如絲般順滑的滾動展示效果何須那麼麻煩,一個class搞定
<div class="scroll-container">預設是橫向滾動
<img src=""/>
<img src=""/>
<img src=""/>
...
</div>
<div class="scroll-container-y">如果是縱向的滾動就加個-y
...
</div>
複製程式碼
效果
flex容器
我想你一定記不住CSS3中flex的具體用法,因此我們對flex進行了細緻的封裝,形成了這個最為強大的佈局容器,他的功能可以說是喪心病狂,但是用法之簡單卻令人髮指。
<div class="flex-container">
這裡填寫內部結構,橫向排列
</div>
<div class="flex-container-col">
這裡填寫內部結構,縱向排列
</div>
複製程式碼
WTF?這就完了,嗯,完了,你沒看錯,就是這麼簡單。下面來看看它都能完成那些操作
你可以額外新增下面4種類別,一共10個輔助class,他可以滿足你的任何需求,如果直接新增到外層節點可以對所有子節點統一控制,如果新增到子節點上,可以額外的對子節點進行單獨的控制。
間隔型別選擇 | 順序翻轉 | 位置控制 | 子節點橫縱向填滿 |
---|---|---|---|
round/between | reverse | top/left/right/bottom/center | vfull/hfull |
我想這些API的封裝已經簡單到讓我懶得去解釋其作用了。媽媽再也不用擔心我記不住flex的用法了。
總結
容器類能夠實現的佈局非常強大,而且使用起來非常簡單,所有的關鍵字class都是非常常用的,更重要的是他們還可以隨意組合,來實現更加複雜的佈局,從你用上Cyan開始,你已經是一個創造者,限制你的不是框架功能,而是你的想象力。
列表
容器類的功能已經足夠強大,但是仍有很大的改進空間。比如我們要實現一個5列的導航,可以使用下面三種方式。
方式一:網格容器或盒容器
<div class="container">
<div class="row">
<div class="col3 text-center" v-for="i in 5">
<img src="" alt=""><span>導航{{i}}</span>
</div>
</div>
</div>
方式二:flex容器
<div class="flex-container">
<div class="flex1 text-center" v-for="i in 5">
<img src="" alt=""><span>導航{{i}}</span>
</div>
</div>
方式三:滾動容器
<div class="scroll-container">
<div v-for="i in 5" style="width:20%" class="text-center">
<img src="" alt=""><span>導航{{i}}</span>
</div>
</div>
複製程式碼
但是如果有兩排或者更多排呢?網格容器可以無修改繼續使用,flex容器需要新增換行屬性,並設定每一個的寬度,滾動容器已經不能使用了(除非放置兩個滾動容器)
<div class="flex-container">
<div class="text-center wrap" v-for="i in 10" style="width:20%">
<img src="" alt=""><span>導航{{i}}</span>
</div>
</div>
複製程式碼
如果此時需要新增分割線呢?你當然可以為使用我們的邊框類為節點新增一個border的class,但是這會導致相鄰的邊框加粗。雖然通過新增我們提供的輔助類完全可以處理這些問題,但是都顯得麻煩,因此我們需要list類
基礎list
list類可以隨意控制列數以及邊框的顯示,每一列所佔的寬度均相等,並且自動在每行的第一個進行浮動的清除,以保證即使在每一項高度不同的時候也能很好的展示。與此同時你可以在將list和前面講過的佈局類容器隨意組合,在此基礎上沒有什麼佈局結構能夠難得住你了。
<div class="list list-col5 border">
<div class="list-item padding20 text-center" v-for="i in 10">
<img src="" alt=""><span>導航{{i}}</span>
</div>
</div>
複製程式碼
元件list
現在考慮下面幾種更復雜的情況:
- list的每一項寬度不同
- 每一項之間有間隔
- 邊框顏色不同意,甚至有的有,有的沒有
- list需要分組,形成類似通訊錄的頁面效果
前三種情況通過list 和flex-container的組合可以解決,但是需要多寫一層DIV,第四種情況需要單獨開發雖然並不複雜。此時我們可以開始使用我們的元件系統了。
<cmui-list :col='[2,7,5]' :space='20' border='#ab2c4f'>三列2:7:5展示,間距20,邊框顏色#ab2c4f
<cmui-list-item>
...
</cmui-list-item>
</cmui-list>
複製程式碼
通過元件我們可以隨意設定每一列所佔的比例,邊框,間距,在item上我們同樣可以對這些屬性進行微調,如果邊框貼合,會自動合併,而且可以無限巢狀,如此一來所有的行列結構就都能實現,通常這種結構會在廣告位的展示上使用,
虛擬list
現在常規的佈局已經沒有搞不定的了,我們再把問題升級一下,如果一個列表有1萬條資料怎麼處理,比如對搜尋結果不斷分頁載入,大量的資料會產生兩個問題:
- 首次渲染效率降低
- 隨著資料量不斷增大頁面越來越卡
此時你需要虛擬列表,它可以將資料儲存到快取中,並且僅對螢幕可視區內進行渲染,即使同時載入數萬條資料依舊非常流暢和高效。
<cmui-virtual-list height="500px" :data="Listdata" v-slot="slotProps">
<p>{{slotProps.item.value}}</p>
</cmui-virtual-list>
複製程式碼
從案例中你可以看到雖然我們要渲染一萬條資料,但實際上僅有很少的節點在不斷更新。
動態輔助
佈局搞定了,但只是結構相似,想要完美匹配設計稿還需要微調,padding/margin /top/bottom/left/right這些值在不同的設計稿中變數非常大,好在移動端螢幕尺寸較小,只需要將所有可能的值提前在CSS中定義好就可以了。padding12表示12畫素響應式填充,paddingh12表示只有水平方向填充。
開玩笑的,CMUI會自動解析你的html結構,並監聽符合格式的class定義,當你為一個DOM節點新增paddingXXX的class的時候,會自動在動態樣式表中生成對應的樣式,並且根據不同的裝置響應成不同的值。你只需要直接用就行了。
提前嚐鮮
前文說過,CMUI包括三個模組,本文也僅對Cyan中的的佈局,元件庫中的列表,方法庫中的動態輔助做了簡介,CMUI的功能遠不止如此,我們正在對文件,案例,主題庫做最後的完善,如果你想提前嚐鮮,可以點選下方連結破解我們官網的二維碼,加入我們的討論群來獲取。