相比于其他的Hybrid H5+APP平臺,MUI也算是自成一派,居正自認為它是國內平臺中最棒的之一,包括web和原生相結合在內的各方面細節都設計的很到位。但MUI有個缺點——開發文檔不夠詳細,學習的過程中會遇到很多坑。在本文中,居正將自己一段時間來摸爬滾打的經驗分享給大家,幫助大家少走點彎路。
如今,移動應用程序的開發已經不僅僅是傳統意義上的iOS、Android雙平臺,Swift、Java兩種開發方式。以WebUI+NativeUI混合架構的Hybrid APP已經漸漸為開發者和用戶們所接受。例如知乎的Android客戶端、網易云音樂的Mac和Android客戶端等采用的都是Web APP開發架構。對開發者來說,只需要掌握HTML和Javascript就可以開發幾乎任意平臺的客戶端,而且開發速率相比于采用原生語言來說大大提高。開發Hybrid APP的平臺有很多,國外有谷歌官方的PWA,國內也有如apicloud、dcloud等廠商在做這類的產品。
居正最近也入了Hybrid APP這個坑,采用的是dcloud家的HBuilder+MUI平臺,官方網站:http://dev.dcloud.net.cn/mui/。相比于其他的平臺,MUI也算是自成一派,居正自認為它是國內平臺中最棒的之一,包括web和原生相結合在內的各方面細節都設計的很到位。但MUI有個缺點——開發文檔不夠詳細,學習的過程中會遇到很多坑。在本文中,居正將自己一段時間來摸爬滾打的經驗分享給大家,幫助大家少走點彎路。
1.開發文檔隨時查
雖然文檔不詳細,但不看文檔是萬萬不可的。由于MUI相關的文檔分布的比較散,這里歸結如下:
MUI框架文檔:http://dev.dcloud.net.cn/mui/window/(打開窗口、事件處理等應用內的基本方法)
HTML5+API文檔:http://www.html5plus.org/doc/h5p.html(通過js調用webview、攝像頭、本地存儲、相冊等手機原生方法的類庫)
2.MUI≠mui.css
MUI其實有兩個意思,一個是MUI開發平臺,一個是mui.css的web ui前端框架,采用的是ios風格(居正個人覺得挺難看的= =)。
你可以用自己的UI框架,這里推薦MaterializeCSS:http://www.materializecss.cn/。
采用自己的UI框架的話就不必寫什么、標簽(這些是為mui.css專門設計的),就和平常開發網頁一樣寫、寫即可。
建議新手不要用mui.css。
3.一個很好的開發實例
官方提供的開發實例是Hello MUI,但主要演示的是mui.css,注釋也比較少。這里推薦自己互聯網上找到的一個開發實例。
滴石APP:https://github.com/uikoo9/dishi
開發筆記:http://uikoo9.com/book/detail/3
閱讀一下整套代碼,會有很大幫助!
4.寫法與順序
前面都是推薦,現在正式開始踩坑。
html文件head里面的東西沒聲明清楚,或者引入js順序不對的話,很容易出錯。這里直接套格式(以采用了MaterializeCSS前端框架為例,每個html文件都同理):
JQuery版本最好在1.10以上,必須在MUI核心js之后、所有自己的js之前引入。
5.mui變量和plus變量分別是什么
mui變量和plus變量都是在MUI核心js里面聲明的。
mui變量中的方法是打開窗口、事件處理等應用內的基本方法。是dcloud平臺自己制作的。
plus變量是通過js調用webview、攝像頭、本地存儲、相冊等手機原生方法的類庫。是HTML5+中國產業聯盟統一制作的。它的文檔里面各種變量各種方法一定要去看!
6.mui.init()、mui.plusReady()和子頁面
在app開發中,若要使用HTML5+擴展api,必須等plusready事件發生后才能正常使用,mui將該事件封裝成了mui.plusReady()方法。
當然你不可能不用到HTML5+API,所以請把業務代碼全部寫到mui.plusReady()里面!
mui.init()用于頁面初始化,也必須調用。
直接套格式(寫在第3點提到的某個頁面專一的js里面):
mui.init();
mui.plusReady(function(){
//業務代碼…
}
需要注意的是mui.init()和mui.plusReady()的執行分不清誰先誰后。所以如果你在mui.init()里面按照官方文檔的說明用subpages創建了一個子頁面,在mui.plusReady()里面是不能直接取得引用的(會報null錯誤)。
故不建議采用官方文檔中的方法在mui.init()里面直接創建subpages!新手可以記住:mui.init()里面什么都不要寫。
也不建議新手用官方推薦的什么雙webview下拉加載上拉刷新來提高性能,比較麻煩而且容易出錯,直接用JQuery插件實現。單webview性能足夠了,一般的設備其實也都不會卡。
如果實在要用子窗口的話建議這樣寫:
mui.init();
mui.plusReady(function(){
var child=plus.webview.create(‘窗口URL’,’窗口ID’,{top:’60px’/*子窗口與父窗口頂部的距離,以免遮住父窗口頂部導航欄*/});//直接用H5+API創建窗口
plus.webview.currentWebview().append(child);//將創建的子窗口添加到父窗口
}
添加完子窗口后,父窗口原來位置上面的東西全部會被擋住。
實例:MUI內置瀏覽器
7.事件處理,用這一個封裝就夠了
MUI文檔中的事件管理有沒有讓你暈頭轉向?這里直接給一個萬能封裝,用它就夠了(放在第3點提到的全局js里面):
function myEvent(obj, event, func){
$(document).off(event, obj).on(event, obj, func);
};
myEvent方法有三個傳參。obj是一個字符串,和JQuery選擇器傳入的參數一模一樣。event是一個字符串,寫事件類型,一般如果是點擊的話就寫tap(不要寫click,習慣要改過來)。func傳入一個匿名方法,里面寫業務代碼。
使用方法,以點擊id為hello的按鈕彈出警告框為例:
myEvent(‘#hello’,’tap’,function(){
alert(‘你好’);
});
8.頁面間傳參,用這一個套路就夠了
MUI的頁面間傳參有各種各樣的方法。這里推薦一個最簡單最高效的:用extras屬性傳參。
A頁面打開B頁面(text.html)代碼:
mui.openWindow({
url:’text.html’,
id:’text01′,
extras:{
content:’我是內容’,
title:’我是標題’
}
});
順便提一下mui.openWindow中的兩個必備參數:
url:目標頁面相對于此頁面的地址(不是相對于業務處理js的地址)
id:字符串數據,打開窗口的唯一標識符。如果打開了一個窗口沒有銷毀,在其他地方又采用此id打開窗口的話就會直接跳到先前打開的那個窗口,并且不會執行里面的mui.plusReady()代碼。
B頁面接收A頁面傳來的兩個參數(必須寫在mui.plusReady()里面):
var content=plus.webview.currentWebview().content;
var title=plus.webview.currentWebview().title;
需要注意的是,extras里面的取名不能取mui.openWindow中存在的參數,例如id、url這樣的,因為調用的方法都是【plus.webview.currentWebview().名字】。否則MUI就不知道你想調用的是這個窗口本身的屬性還是傳過來的參數。這一點應該算是MUI的設計缺陷。
9.網絡請求必須用mui.ajax,調試必須用真機或模擬器
你可能習慣了JQuery的$.ajax方法,但在mui開發里面必須用mui.ajax,否則會出現跨域錯誤問題。調試的時候不要用HBuilder自帶的內置瀏覽器調試,必須用真機或模擬器中的HBuilder基座調試,否則也會跨域報錯。
mui.ajax和$.ajax參數基本一樣,返回的是一個XMLHttpRequest對象。
10.manifest.json中的build版本號要手動改
版本號有兩種,一種是應用版本名稱(如:1.2),一種是build版本號(如:65)。應用市場判斷APP有沒有升級用的是build版本號而不是應用版本名稱。但HBuilder中build版本號并不是自動遞增的,需要手動改。如果沒改的話應用升級發布到應用市場里面會出現奇怪的錯誤。
打開manifest.json切換到代碼視圖,找到:
其中name即為應用版本名稱,code即為build版本號。每次發布應用的時候code值要改成比上次大的數。
以上是為大家整理的若干條新手易錯點,希望大家在開發中少走彎路!
本文首發于淀粉月刊:https://dfkan.com
原作者:居正
發布時間:2018年7月11日