最接近原生APP體驗的高性能前端框架——MUI
前 言
MUI有三大特點:
輕量
追求性能體驗,是我們開始啟動MUI項目的首要目標,輕量必然是重要特征;
MUI不依賴任何第三方JS庫,壓縮後的JS和CSS文件僅有100+K和60+K
原生UI
鑒於之前的很多前端框架(特別是響應式布局的框架),UI控件看起來太像網頁,沒有原生感覺,因此追求原生UI感覺也是我們的重要目標
MUI以iOS平臺UI為基礎,補充部分Android平臺特有的UI控件
流暢體驗
下拉刷新,側滑導航,滑動觸發操作菜單
1、新手指南 |
1.1 快速體驗
1. 下載Hello mui App
點擊下載 已打包好的Hello mui 手機app,直接在手機上體驗mui的控件UI及能力展示;
2. 創建Hello mui工程
可從https://www.dcloud.io下載Hbuilder,選擇新建“移動APP”,並選擇“Hello MUI”工程模板,創建工程;然後通過數據線將手機連接上電腦,點擊運行,就可以在手機上體驗MUI的各項能力。
1.2快速構建頁面
1. 新建含mui的HTML文件
在Hbuilder中,新建HTML文件,選擇”含mui的HTML“模板,可以快速生成mui頁面模板,該模板默認處理了mui的js、css資源引用。
2.輸入mheader
頂部標題欄是每個頁面都必需的內容,在Hbuilder中輸入mheader,可以快速生成頂部導航欄。
3.輸入mbody
除頂部導航、底部選項卡兩個控件之外,其它控件都建議放在.mui-content
控件內,在Hbuilder中輸入mbody,可快速生成包含.mui-content
的代碼塊。
4.完整代碼塊請參考
2、 UI組件 |
以iOS 7為基礎,補充部分Android特有控件
下面介紹常用的組件
2.1折疊面板
折疊面板從二級列表中演化而來,dom結構和二級列表類似,如下:
<ul class="mui-table-view"> <li class="mui-table-view-cell mui-collapse"> <a class="mui-navigate-right" href="#">面板1</a> <div class="mui-collapse-content"> <p>面板1子內容</p> </div> </li> </ul>
可以在折疊面板中放置任何內容;折疊面板默認收縮,若希望某個面板默認展開,只需要在包含.mui-collapse
類的li
節點上,增加.mui-active
類即可;mui官網中的方法說明,使用的就是折疊面板控件。
2.2圖片輪播
圖片輪播繼承自slide插件,因此其DOM結構、事件均和slide插件相同;
DOM結構
默認不支持循環播放,DOM結構如下:
<div class="mui-slider"> <div class="mui-slider-group"> <div class="mui-slider-item"><a href="#"><img src="1.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="2.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="3.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="4.jpg" /></a></div> </div> </div>
假設當前圖片輪播中有1、2、3、4四張圖片,從第1張圖片起,依次向左滑動切換圖片,當切換到第4張圖片時,繼續向左滑動,接下來會有兩種效果:
- 支持循環:左滑,直接切換到第1張圖片;
- 不支持循環:左滑,無反應,繼續顯示第4張圖片,用戶若要顯示第1張圖片,必須連續向右滑動切換到第1張圖片;
當顯示第1張圖片時,繼續右滑是否顯示第4張圖片,是同樣問題;這個問題的實現需要通過.mui-slider-loop
類及DOM節點來控制;
若要支持循環,則需要在.mui-slider-group
節點上增加.mui-slider-loop
類,同時需要重復增加2張圖片,圖片順序變為:4、1、2、3、4、1,代碼示例如下:
<div class="mui-slider"> <div class="mui-slider-group mui-slider-loop"> <!--支持循環,需要重復圖片節點--> <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="4.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="1.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="2.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="3.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="4.jpg" /></a></div> <!--支持循環,需要重復圖片節點--> <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="1.jpg" /></a></div> </div> </div>
JS Method
mui框架內置了圖片輪播插件,通過該插件封裝的JS API,用戶可以設定是否自動輪播及輪播周期,如下為代碼示例:
//獲得slider插件對象 var gallery = mui(‘.mui-slider‘); gallery.slider({ interval:5000//自動輪播周期,若為0則不自動播放,默認為0; });
因此若希望圖片輪播不要自動播放,而是用戶手動滑動才切換,只需要通過如上方法,將interval參數設為0即可。
若要跳轉到第x張圖片,則可以使用圖片輪播插件的gotoItem方法,例如:
//獲得slider插件對象 var gallery = mui(‘.mui-slider‘); gallery.slider().gotoItem(index);//跳轉到第index張圖片,index從0開始;
註意:mui框架會默認初始化當前頁面的圖片輪播組件;若輪播組件內容為js動態生成時(比如通過ajax動態獲取的營銷信息),則需要在動態生成完整DOM (包含mui-slider
下所有DOM結構) 後,手動調用圖片輪播的初始化方法;代碼如下:
//獲得slider插件對象 var gallery = mui(‘.mui-slider‘); gallery.slider({ interval:5000//自動輪播周期,若為0則不自動播放,默認為0; });
2.3柵格
柵格系統簡介:
MUI 提供了非常簡單實用的12
列響應式柵格系統。使用時只需在外圍容器上添加.mui-row
,在列上添加 .mui-col-[sm|xs]-[1-12]
,即可柵格參數:
尺寸 | 超小屏幕(<400px)(Extrasmall) | 小屏幕(≥400px) Small | ||
---|---|---|---|---|
類前綴 | .mui-col-xs-[1-12] |
.mui-col-sm-[1-12] |
||
列(column)數 | 12 | |||
可嵌套 | 是 |
實例:
左側:通過定義.mui-col-sm-6
類在大屏(≥400px)設備上會展現為並排的兩列,而.mui-col-xs-12
在小屏(<400px)設備上會覆蓋之前定義的類展現為水平排列
<div class="mui-content"> <div class="mui-row"> <div class="mui-col-sm-6 mui-col-xs-12"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> Item 1 </a> </li> </div> <div class="mui-col-sm-6 mui-col-xs-12"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> Item 1 </a> </li> </div> </div> </div>
實例:多余的列將會另起一行排列
左側:如果在一個.mui-row
內包含的列(column)大於12個,包含多余列(column)的元素將作為一個整體單元被另起一行排列。
右側:如果不足12個列將不會撐滿整個.mui-row
容器
<div class="mui-content"> <div class="mui-row"> <div class="mui-col-sm-8"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> Item 1 </a> </li> </div> <div class="mui-col-sm-6"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> Item 1 </a> </li> </div> </div> </div>
實例:通過為列
設置padding
屬性,從而創建列與列之間的間隔
兩列之間白色區域為左側列的padding
<div class="mui-content"> <div class="mui-row"> <div class="mui-col-sm-6" style="padding-right: 20px;"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> Item 1 </a> </li> </div> <div class="mui-col-sm-6"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> Item 1 </a> </li> </div> </div> </div>
3 下拉刷新功能 |
為實現下拉刷新功能,大多數 H5 框架都是通過 DIV 模擬下拉回彈動畫,在低端 android 手機上,DIV 動畫經常出現卡頓現象(特別是圖文列表的情況); mui 通過使用原生 webview 下拉刷新解決這個 DIV 動畫的卡頓問題,並且拖動效果更加流暢;
這裏提供兩種模式的下拉刷新,以適用不同場景:
3.1單webview模式
效果展示:
動畫原理:
下拉刷新時,觸發的是原生下拉刷新控件,而整個webview
位置不會發生變化,所以不會在拖動過程中發生DOM重繪,當控件拖動到一定位置觸發動態加載數據以及刷新操作。此模式下拉刷新,相比雙webview 模式,不創建額外 webview,性能更優。
使用方法:
mui 初始化時設置pullRefresh
各項參數,與雙 webview 模式的子頁面設置是一樣的。
說明:
1、DOM結構無特殊要求,只需要指定一個下拉刷新容器標識即可mui.init({ pullRefresh : { container:"#refreshContainer",//下拉刷新容器標識,querySelector能定位的css選擇器均可,比如:id、.class等 down : { style:‘circle‘,//必選,下拉刷新樣式,目前支持原生5+ ‘circle’ 樣式 color:‘#2BD009‘, //可選,默認“#2BD009” 下拉刷新控件顏色 height:‘50px‘,//可選,默認50px.下拉刷新控件的高度, range:‘100px‘, //可選 默認100px,控件可下拉拖拽的範圍 offset:‘0px‘, //可選 默認0px,下拉刷新控件的起始位置 auto: true,//可選,默認false.首次加載自動上拉刷新一次 callback :pullfresh-function //必選,刷新函數,根據具體業務來編寫,比如通過ajax從服務器獲取新數據; } } });
模式說明:
優點
1、相比雙webview,不創建額外子webview性能消耗更少
2、下拉拖動過程中不會發生重繪,性能消耗更少
缺點:
目前僅僅支持circle樣式及其樣式的自定義
3.1雙webview模式
效果展示:
動畫原理:
使用雙 webview 模式的下拉刷新,創建一個子 webview 添加列表;拖動時,拖動的是一個完整的 webview,避免了類似 DIV 拖動流暢度不好的問題,回彈動畫使用原生動畫;在 iOS 平臺,H5 的動畫已經比較流暢,故依然使用 H5 方案。兩個平臺實現雖有差異,但 mui 經過封裝,可使用一套代碼實現下拉刷新。
使用方法:
主頁面內容比較簡單,只需要創建子頁面即可:
mui.init({ subpages:[{ url:pullrefresh-subpage-url,//下拉刷新內容頁面地址 id:pullrefresh-subpage-id,//內容頁面標誌 styles:{ top:subpage-top-position,//內容頁面頂部位置,需根據實際頁面布局計算,若使用標準mui導航,頂部默認為48px; .....//其它參數定義 } }] });
iOS平臺的下拉刷新,使用的是 mui 封裝的區域滾動組件, 為保證兩個平臺的 DOM 結構一致,內容頁面需統一按照如下 DOM 結構構建:
<!--下拉刷新容器--> <div id="refreshContainer" class="mui-content mui-scroll-wrapper"> <div class="mui-scroll"> <!--數據列表--> <ul class="mui-table-view mui-table-view-chevron"> </ul> </div> </div>
其次,通過 mui.init 方法中 pullRefresh 參數配置下拉刷新各項參數,如下:
mui.init({ pullRefresh : { container:"#refreshContainer",//下拉刷新容器標識,querySelector能定位的css選擇器均可,比如:id、.class等 down : { height:50,//可選,默認50.觸發下拉刷新拖動距離, auto: true,//可選,默認false.首次加載自動下拉刷新一次 contentdown : "下拉可以刷新",//可選,在下拉可刷新狀態時,下拉刷新控件上顯示的標題內容 contentover : "釋放立即刷新",//可選,在釋放可刷新狀態時,下拉刷新控件上顯示的標題內容 contentrefresh : "正在刷新...",//可選,正在刷新狀態時,下拉刷新控件上顯示的標題內容 callback :pullfresh-function //必選,刷新函數,根據具體業務來編寫,比如通過ajax從服務器獲取新數據; } } });
模式說明:
優點:可自定義下拉刷新樣式。
缺點:性能消耗大,DOM結構需要重新配置。
結尾
MUI的定位。
MUI的定位是:最接近原生體驗的移動App的UI框架
基於mui的定位,產生了mui的幾個特點,輕、小、只涉及UI、只為移動App而生、界面風格原生化。
所以請大家註意,mui有所為有所不為:
-
mui不是jq,不封裝dom操作
與ui無關的mui不做,你願意用jq或zepto就自己用,並不沖突。
但我們並不建議在移動App裏引入jq或zepto這些框架,原因如下:- 為了性能,層層封裝的框架,尤其是遍歷循環dom時,影響效率,尤其在低端Android手機上,我們費死勁了才把性能以毫秒為單位一點點提升,搞這個的dom框架進來就讓很多努力又付諸東流。
- 原生JS挺簡單,為何需要jq?
jq的成功當時是因為ie6、7、8、9、10、chrome、ff這些瀏覽器不兼容,讓開發者崩潰,而且pc上瀏覽器性能好,跨平臺兼容也不影響性能。但jq根本就不是為手機設計的。
手機上只有webkit瀏覽器(忽略wp,反正mui不支持wp),根本就不需要jq這種封裝框架來操作dom。
而且HBuilder提供了代碼塊來簡化開發,敲dg、dq,直接生成document.getElementById("")、document.querySelectorAll(""),非常快捷方便,而且執行性能非常高,而且沒有瀏覽器兼容問題。
發現很多開發者只會jq,反正想繼續在App裏使用jq沒有問題。但也建議大家多學學js本身。
mui與vue、react、angular也不是一個層面的東西,可以在一個工程裏混合使用。但在大多數ui控件上,應該直接使用mui的寫法,因為mui的繪制是最樸素的HTML繪制,不是經過js操作的繪制,這種方案的效率比經過js繪制的效率要高很多。只有必須經過js操作才能渲染的控件,比如ajax聯網後填充的list,此時使用vuew或react都可以。
-
mui、HTML5+、5+Runtime的關系說明
mui是一個前端框架,HTML5+是一套HTML5能力擴展規範,HTML5+ Runtime是實現HTML5+規範的強化瀏覽器引擎。
有點類似於bootstrap、w3c和chrome os的關系。
HTML5+規範隸屬於http://www.html5plus.org,定義了HTML5規範中沒有但開發者做App需要的擴展規範。
DCloud的5+ Runtime完整的實現了HTML5+規範。同時5+ Runtime還實現了Native.js,一種通過js調用幾十萬原生API的技術。
為了提升體驗,mui勢必會調用一些5+Rutime的增強能力,主要是plus.webview、plus.nativeobj和plus.nativeUI。
但mui不是要替代HTML5Plus,以後也無計劃替代把所有5+的api都包一層。
mui是把一些常用的窗體操作封裝了,但這種封裝適應面也是有限的,遇到復雜窗體管理,還是要仔細了解plus的api。
所以,- 有人抱怨mui的文檔不全,其實是缺本文,本文終於說清楚mui做什麽不做什麽了。詳細的mui文檔要去下方提示的mui官網查看。
- 有人抱怨mui api不全,其實是沒去看plus的api。知原理、知如何封裝,方能融匯貫通。
- 有人抱怨Hello mui示例代碼裏寫的mui的方法,為何文檔裏沒有,是因為有些方法是內部工程師簡化開發中的封裝,未考慮通用設計,還不足以開放為標準api,所以文檔裏沒介紹。
-
mui有插件體系
為了簡化開發者的多端發布開發,mui在核心庫之外,補充了一些插件,這些插件不一定是ui相關,也有業務相關。
在Hello mui示例裏下方的示例模板,基本都屬於插件。這些插件的使用需要加載mui標準庫之外的js等資源。
mui是一個開源項目,請前往托管在github的mui官網查看詳細介紹
這裏是mui發布時的演講視頻:http://v.youku.com/v_show/id_XNzYyOTEyMjcy.html
最接近原生APP體驗的高性能前端框架——MUI