uniapp從0到1開發(fā)指南, 跨平臺開發(fā)新手必看

前排提示:??非推廣軟文

微信公眾號: 因卓誒勉吻;此文已同步到因卓誒blog

Uniapp這兩年是Vue開發(fā)者很喜歡的跨平臺開發(fā)框架卤恳,作為一個國產(chǎn)開發(fā)框架,其實文檔和周邊工具都對國人非常友好亲族,但是由于框架本身的跨多端所以從誕生以來都被很多開發(fā)者詬病“坑太多”种呐,那么這篇文章將結(jié)合本人2年Uniapp開發(fā)經(jīng)驗,給新手小白一個從0到1的教程&踩坑說明噩死。


目錄

  • 歷史

    1. uniapp編譯器發(fā)展歷程

  • 踩坑經(jīng)驗(框架部分)

    2. 條件編譯

    3. onLoad和onShow 用合適的生命周期

    4. 觸底加載和下拉加載的實例

    5. 如何操作DOM

    6. 上傳圖片/文件

    7.?websocket

    8. Nvue介紹

    9. SubNvue介紹

    10. 全局通信

    11. h5+API介紹

    12. 應(yīng)用內(nèi)更新和wgt的介紹和使用

    13. APP自定義tabbar

    14. 如何協(xié)同原生插件來工作

    15. manifest.json簡介

    16. uniapp如何請求數(shù)據(jù)

    17. uniapp應(yīng)該用什么方式創(chuàng)建項目

  • 社區(qū)

  • 插件市場

  • HbuilderX

    18. 簡介和快速開發(fā)的準備工作

    19. 打包APP前的準備

    20. uniapp的debug

    21. APP打包

    22. 關(guān)于IOS

  • 拓展閱讀


  • 歷史

    Uniapp從誕生到目前颤难,經(jīng)歷了3次重大變革,首先是最初借鑒了Mpvue的模板語法(非自定義組件模式)這個模式是性能最差且支持Vue語法有很多欠缺的版本已维,在當時我認為Uniapp開發(fā)APP是滿足不了企業(yè)需要的行嗤,倒是做一款小程序開發(fā)框架很是不錯。

    在2018-2019這個時間段垛耳,也就是uniapp是模板編譯模式的時代栅屏,網(wǎng)上對于uniapp也是褒貶不一,社區(qū)的完善度還有官方的UI支持都是非常落后的堂鲜,唯一吹一吹的就是QQ群當時很火栈雳,官方的解答和處理BUG的速度還很快。我個人認為web前端跨平臺框架受到了很多原生安卓&IOS開發(fā)者的排擠泡嘴,拿生成的代碼質(zhì)量和性能說事甫恩,說不定自己也沒有使用過。

    在我接觸uniapp不久之后(大概幾個月)就出了自定義組件模式酌予,這個組件模式相當于革命性的更新磺箕,支持用戶編寫的Vue組件轉(zhuǎn)換成微信小程序的自定義組件,基于這個uniapp在安卓平臺上放置了JS Core抛虫,從這個時候開始uniapp開始慢慢的被更多的原生開發(fā)者接受松靡,因為跨平臺開發(fā)的好處是在是太大了。

    那么接下來的一次更新讓我瞠目結(jié)舌建椰,因為由于19年的年底這一段時間我沒有從事uniapp開發(fā)雕欺,直到今年才繼續(xù)開發(fā)uniapp,發(fā)現(xiàn)了uniapp的一次重大更新:“v3引擎”。

    V3引擎同樣也是Dcloud自研屠列,我認為主要的更新在于安卓和IOS端啦逆,開始注重了啟動速度和包體積大小,我們可以在V3更新說明中看到笛洛。

    到此為止夏志,我認為uniapp到此刻應(yīng)該是推廣的時候,讓前端開發(fā)人員坐上跨平臺開發(fā)的小車車苛让。

    踩坑經(jīng)驗(框架部分)

    首先沟蔑,uniapp絕大部分官網(wǎng)描述的API,比如設(shè)備信息狱杰,內(nèi)存瘦材,藍牙等等都是原生開發(fā)比較常用的,uniapp的優(yōu)點就體現(xiàn)出來了仿畸,不同平臺的各種API都會略微有差異食棕,那么我們應(yīng)該仔細看文檔。

    如果文檔已經(jīng)說明此API存在【平臺差異】颁湖,那么我們應(yīng)該注意API下方可能會有這樣的【tips】

    這也是文檔的一個小坑宣蠕,很多新手如果不仔細看文檔,在調(diào)API的時候不考慮兼容問題甥捺,導(dǎo)致在小程序/APP中抢蚀,比如出現(xiàn)安卓和ios功能不一致的問題,如果看仔細文檔镰禾,那么百分之99以上的問題都會在tips中說明皿曲。

    注釋魔法:條件編譯

    其次uniapp還有一個非常強大的功能【條件編譯】,這也是開發(fā)中非常常用的功能吴侦,如下屋休,我們可以使用像C語言中核心注釋,注釋中的代碼片段將在指定的平臺出現(xiàn)备韧,反之亦然劫樟;

    <!-- #ifdef APP-PLUS -->代碼片段,APP-PLUS代表著APP端织堂,ifdef包含叠艳,ifndef不包含,多個平臺可以用空格隔開??<!--?#endif?--><!--?#ifndef?APP-PLUS-NVUE?APP-NVUE?MP?-->編譯多個平臺<!--?#endif?-->

    條件編譯可以存在于任何地方易阳,template css js附较;同樣uniapp支持更強大的條件編譯:比如支持在page.json中進行判斷,達到不同端不同的分包功能潦俺;靜態(tài)資源也可以進行條件編譯拒课,通過static下構(gòu)建platform目錄即可把不同的靜態(tài)資源編譯到不同的平臺上去徐勃;那么同理也可以把頁面進行條件編譯,即不同平臺不同頁面;

    onLoad&onShow

    我們已經(jīng)了解了uniapp極具特色的條件編譯之后早像,我們可以了解一下uniapp必不可少的生命周期僻肖,uniapp在目前版本支持vue的所有生命周期以及絕大多數(shù)API;比較重要的nextTickcompile不支持卢鹦,組件選項中比較重要的是render函數(shù)不支持檐涝,具體更多的支持特性表請移步官網(wǎng)查看(https://uniapp.dcloud.io/use?id=vue%e7%89%b9%e6%80%a7%e6%94%af%e6%8c%81%e8%a1%a8),下面我們將推薦開發(fā)中常用的生命周期以及應(yīng)用場景:

    onLoad(e){??// 組件渲染未完成但是已創(chuàng)建的鉤子法挨,與Vue的create同理,這里推薦使用onLoad代替create??// 行參e可以獲取當前路徑的參數(shù)幅聘,比如當前頁面是b凡纳,如果a跳轉(zhuǎn)到b頁面是如下url:??//?/pages/index/a?type=1? console.log(e.type); // "1"}

    onShow(){??//?用于監(jiān)聽:頁面在屏幕上顯示時觸發(fā),從APP應(yīng)用后臺到APP前臺也會觸發(fā)??//?通常我們可以使用這個鉤子做一些非列表頁面的數(shù)據(jù)刷新(比如從上一個頁面返回帝蒿,然后此頁面刷新)}

    觸底加載&下拉加載的實踐

    APP中有一個非常常見的場景叫做觸底加載荐糜,那么針對APP頁面級別的滾動觸底回調(diào)就是onReachBottom

    onReachBottom(){??//?在這里進行當前頁加1??this.listConfig.nowPage ++;??// 調(diào)用加載列表的方法??this.initList();}methods: {??async initList(){????const?toList?=?await?getALLTodoList({??????limit:?this.listConfig.pageSize,??????offset:?(this.listConfig.nowPage?-?1)?*?this.listConfig.pageSize),????})??}}

    那么下拉加載這個功能在APP中非常常見,我們需要在page.json中對應(yīng)的節(jié)點style下開啟下拉加載

    "enablePullDownRefresh": true

    那么對應(yīng)頁面的監(jiān)聽鉤子將會觸發(fā)

    onPullDownRefresh(){??//?用戶下拉了頁面}

    【注意事項】不管是觸底加載和下拉刷新此實例都是針對頁面級別葛超,如果你不知道何為頁面級暴氏,那么請耐心看完uniapp的組件相關(guān)內(nèi)容,在uniapp組件中有一個<scroll-view>绣张,它提供一個滾動視圖答渔,在這個滾動視圖中有著自己的下拉加載和觸底加載方法,因此如果頁面中存在此組件侥涵,開發(fā)者應(yīng)該妥善處理組件級別的滾動和頁面級別的滾動沼撕,這是非常重要的。

    如何操作DOM芜飘?

    我們通常在開發(fā)Vue應(yīng)用時务豺,很少直接操作DOM,在uniapp中沒有暴漏DOM這個概念嗦明,但是我們可以通過指定的API去操作DOM笼沥,盡管這是非常不建議的,但是在某些業(yè)務(wù)場景不得不說

    它是很方便的娶牌;

    let?tabInfo?=?uni.createSelectorQuery().select("#tab");tabInfo.boundingClientRect((data)?=>?{??//?目標區(qū)域的信息}).exec();

    文件的選擇

    uniapp在文件的選擇上非常豐富奔浅,舉一個例子比如說圖片,我們可以在文檔中很清楚的查詢到對應(yīng)的API裙戏,通過封裝的API我們可以通過配置參數(shù)來chooseImage乘凸,然后拿到臨時路徑再繼續(xù)上傳;

    uni.chooseImage({    count: 6, //默認9    sizeType: ['original', 'compressed'], //可以指定是原圖還是壓縮圖累榜,默認二者都有    sourceType: ['album'], //從相冊選擇    success: function (res) {???????//?臨時路徑 res.tempFilePaths???????uni.uploadFile({            url: '', //僅為示例营勤,非真實的接口地址            filePath: tempFilePaths[0],            name: 'file',            formData: {                'user': 'test'            },            success: (uploadFileRes) => {                console.log(uploadFileRes.data);            }        });    }});

    重點來了灵嫌,我們上傳圖片固然簡單,但是上傳文件是非常難的葛作,我們?nèi)绻贏PP端想做一個上傳文件的功能寿羞,就要盡量使用html的幫助,由html的input type=“file”來做上傳赂蠢,那么首先得簡單了解一下利用html如何上傳文件绪穆。

    1. 首先我們需要使用h5+API中的webview相關(guān)的API

    let wv = plus.webview.create("", "/hybrid/html/index.html", {  'uni-app': 'none', //不加載uni-app渲染層框架,避免樣式?jīng)_突  top: 0,  height: '100%',  background: 'transparent'  }, {    url,    header,    key: name,    ...formData,  });wv.loadURL("/hybrid/html/index.html"); // 加載本地的html文件currentWebview.append(wv);?//?把html追加到當前頁面中

    把本地的HTML加載到APP之上之后虱岂,我們在本地編寫的HTML文件中引入對應(yīng)uni.webview文件以及需要的業(yè)務(wù)JS文件玖院,我們在HTML是這樣做的(核心代碼)

    <script?type="text/javascript"?src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script><script?src="js/h5-uploader.js"?type="text/javascript"?charset="utf-8"></script>

    我們在本地編寫的業(yè)務(wù)JS

    xhr.onreadystatechange?=?(ev)?=>?{    if(xhr.readyState == 4) {      if (xhr.status == 200) {????????progress.innerText?=?'成功';?????????//??從這里可以看出,上傳成功之后第岖,我們通過改變html的title把信息返回        title.innerText = `${file.name}|^$%^|${src}|^$%^|${suffix}`;      }      else {        progress.innerText = '上傳失敗了';??????}      setTimeout(()=>{        tis.style.display = 'none';        // 上傳成功难菌,關(guān)閉了上傳webview的窗口        plus.webview.currentWebview().close();??????},1000);    }  };  xhr.send(formData);

    當index.html的title變化之后,在vue組件創(chuàng)建webview的代碼之后蔑滓,我們可以在當前webview去監(jiān)聽標題的變化郊酒。

    //?wv就是plus.webview.create的返回,上述代碼有舉例子wv.addEventListener('titleUpdate', ({  title}) => {  console.log(title)}

    那vue組件拿到回調(diào)信息之后键袱,就可以正常拿到圖片信息去在頁面中渲染燎窘。

    順便說一句,在文檔的后面蹄咖,會給大家介紹uniapp相關(guān)生態(tài)褐健,一些業(yè)務(wù)組件插件都會在相關(guān)生態(tài)中查詢到。

    websocket

    oh比藻,又到了這個該死的東西了铝量,今年的一段時間內(nèi),在uniapp上使用websocket可是真的太難了银亲,先說一下事情的經(jīng)過慢叨,我司開發(fā)的APP中本來使用了聊天相關(guān)功能,之后在部分業(yè)務(wù)中加入了websocket务蝠,前端需要根據(jù)websocket實時獲取一些信息拍谐,在測試APP的時候發(fā)現(xiàn),當2個websocket并行連接的時候馏段,發(fā)現(xiàn)只有一個連接能有效的發(fā)送和接受消息轩拨,無奈只好去文檔中尋找答案。

    App平臺自定義組件模式下院喜,以及支付寶小程序下亡蓉,所有 vue 頁面只能使用一個 websocket 連接。App下可以使用 plus-websocket 插件替代實現(xiàn)多鏈接喷舀。App平臺砍濒,2.2.6+起支持多個socket鏈接淋肾,數(shù)量沒有限制。

    uniapp-websocket文檔

      import socket from 'plus-websocket'  // #ifdef APP-PLUS  Object.assign(uni, socket)  // #endif

    通過把依賴中的socket合并到uni中爸邢,把uni中原本封裝的socket進行替換樊卓;

    Nvue

    uniapp支持用戶編寫.nvue的組件,那么此組件將會使用改進后的weex引擎進行渲染杠河,提供了原生渲染的能力碌尔,那么如果你是weex用戶如果用nvue寫,那么全程和weex的寫法無異券敌,如果是普通的vue開發(fā)者使用nvue開發(fā)唾戚,那么將注意,nvue對于css和js的限制有非常多待诅,尤其是css很多常用的簡寫都將不能支持颈走,所以我們需要額外查詢對應(yīng)的weex框架的文檔。

    那么我們在APP中有必要全部使用nvue原生渲染么咱士,使用普通vue組件進行webview渲染有什么缺點么?那么我建議APP中 核心/用戶訪問次數(shù)多/需要更強勁的性能的頁面可以使用nvue轧钓,其余普通頁面我們?nèi)匀豢梢允褂胿ue頁面序厉。

    那么如果是weex用戶轉(zhuǎn)uniapp,可以全項目使用nvue毕箍,uniapp支持純原生渲染模式弛房,可以減少APP包體積,也可以減少內(nèi)存占用而柑,因為此時webview相關(guān)依賴是不存在的文捶。使用nvue開發(fā),即保留了原weex開發(fā)者的習慣又可以提供強大的API能力媒咳,這是非常讓人興奮的開發(fā)體驗粹排。

    SubNvue

    subNvue本質(zhì)上是一個nvue組件,支持在普通vue頁面之上運行涩澡,subNvue能覆蓋map顽耳,video等原生組件,uniapp有很多辦法支持覆蓋原生組件妙同,subNvue是我認為最好的方法射富,因為相比<cover-view>組件,不能嵌套粥帚,而且寫起來和原頁面耦合胰耗;又和webview相比,需要原生h5+api做技術(shù)支撐芒涡,nvue相對來說更多vue開發(fā)者友好柴灯。

    實例:由于首頁有swiper那么懸浮的頭部需要遮擋住swiper卖漫,在pages.json中注冊即可

    ?"subNVues":?[{?????????????"id":?"indexTitle",?//?唯一標識???????????????"path":?"pages/index/subNVue/indexTitle",?//?頁面路徑???????????????"style":?{???????????????"position":?"fixed",???????????????"dock":?"top",???????????????"background":?"transparent"?????????????}???????????}]

    uni全局通信

    在uniapp中,vue弛槐,nvue組件中進行信息傳遞是很難的懊亡,尤其是vue和nvue中的信息傳遞我們可以通過全局通信的方式來做業(yè)務(wù)邏輯。

    uni.$emit('update',{msg:'我是首頁乎串,用戶下滑了'})

    uni.$on('update',function(data){????console.log("我是subnvue頭部店枣,你下滑了,那我就改變自身的透明度動畫")})

    適用場景:

    vue?與?nvue叹誉,nvue?與?vue?間的通訊tabbar?頁面之間的通訊父頁面與多級子頁面間的通訊

    uniapp-emit文檔

    注意事項:

    1. 只有在頁面打開時候才能注冊或者監(jiān)聽

    h5+API

    其實像uniapp這樣的框架(或者其他的跨平臺框架)我認為h5+api帶動了整個相關(guān)技術(shù)鸯两,我們在沒有這樣框架的時候,都是使用h5+api完成一個又一個優(yōu)秀的APP长豁,這都離不開這個非常強大的API

    在前面的demo中钧唐,我們或多或少地看到了h5API的影子,下面我們再復(fù)述一遍在uniapp中使用h5+API時的一些注意事項匠襟,這非常重要虐沥。

    首先uniapp內(nèi)置了HTML5+引擎昭伸,我們可以直接調(diào)用h5+相關(guān)規(guī)范,但是在小程序,H5端并沒有對應(yīng)的規(guī)范拓展务唐,所以在這些平臺不會識別“?plus”這個變量掂铐,所以我們需要寫條件編譯

    // #ifdef APP-PLUSconsole.log(plus)//?#endif

    在普通的H5項目中埠巨,我們?nèi)绻褂肏5+API随闺,我們需要進行ready,但是在uniapp不需要ready淮阐,直接上去就是一套軍體拳就是干叮阅。

    還有我們使用一些監(jiān)聽事件的時候,由于uniapp沒有document這個對象泣特,所以需要使用

    plus.globalEvent.addEventListener("這里寫h5+拓展的事件")

    應(yīng)用內(nèi)更新&WGT的使用

    應(yīng)用內(nèi)更新和WGT這一塊是每一個APP不可缺少的部分浩姥,所以我這里會比較詳細的做一些介紹和實踐。

    首先我們來了解一下WGT是干嘛的状您。wgt是APP資源更新包及刻,通常來講這個包體積很小,只有1m 2m左右竞阐,APP在沒有拓展原生模塊下或者沒有增加修改一些原生的插件情況(如果不懂這個概念缴饭,后面會講到)APP是可以使用wgt資源包升級的,整個升級過程用戶可以是“無感知的”骆莹,我們通常在APP中可以看到所謂的升級提示颗搂,這個是有感知的;而有的時候你并沒有升級這個APP缺發(fā)現(xiàn)ui變化幕垦,功能變化丢氢,那么這個時候就是無感知升級傅联,技術(shù)手端也有很多,比如云端更新代碼疚察,在uniapp中我們可以用wgt來實現(xiàn)這樣的功能蒸走。

    我們先來APP普通的有感知更新,uniapp的實例貌嫡。首先請求接口去請求服務(wù)器比驻,拿到最新版本的下載地址,在這之前我們需要判斷當前APP的版本號岛抄,那么這里就有一個小坑别惦,我們千萬不要使用下面這個API獲取版本號。

    plus.runtime.version

    我們?nèi)绻褂脀gt作為資源升級包的話夫椭,那么此API獲取的版本號不是準確的掸掸,它會獲取APP內(nèi)核的應(yīng)用版本號,我們必須要使用

    plus.runtime.getProperty(plus.runtime.appid,function(inf){     console.log(inf.version)});

    我們用此API獲取到的版本號去數(shù)據(jù)庫比對(前方偽代碼):

    // 比對版本方法, 此方法網(wǎng)友提供蹭秋,侵權(quán)刪除const compare = (curV, reqV) => {    if (curV && reqV) {      //將兩個版本號拆成數(shù)字      var arr1 = curV.split('.'),        arr2 = reqV.split('.');      var minLength = Math.min(arr1.length, arr2.length),        position = 0,        diff = 0;      //依次比較版本號每一位大小扰付,當對比得出結(jié)果后跳出循環(huán)(后文有簡單介紹)      while (position < minLength && ((diff = parseInt(arr1[position]) - parseInt(arr2[position])) == 0)) {        position++;      }      diff = (diff != 0) ? diff : (arr1.length - arr2.length);      //若curV大于reqV,則返回true      return diff >= 0;    } else {      //輸入為空      return false;    }}const downLoadFail?=?()?=>?{    uni.hideToast();    uni.showToast({      title: "下載新版本失敗仁讨,請在設(shè)置頁面檢查更新再試",      duration: 2000,      icon: "none",      position: "bottom"    });}// 獲取更新列表悯周,取最新的更新包const?updatePackageList?=?await?getUpdatePackageList();if(compare(updatePackageList[0].version,?"根據(jù)上面的方法獲取的版本號")){??// 如果存在更新??// 整包更新  uni.downloadFile({    url: "整包APK的下載地址(非wgt包地址)",    success: res => {      if (res.statusCode === 200) {????????//?下載之后打開臨時路徑的文件        plus.runtime.openFile(res.tempFilePath);      }else {        downLoadFail(); // 調(diào)用更新失敗的方法      }    },    fail: error => {      downLoadFail(); // 調(diào)用更新失敗的方法    }  });}

    以上是普通的整包升級的偽代碼,如果遇到強制更新陪竿,非強制更新,即開發(fā)者需要自己控制對應(yīng)的button屠橄,這里就不闡述了族跛。

    對于wgt的更新,相比整包更新有一定區(qū)別锐墙,因為整包更新非常簡單礁哄,無非就是下載apk文件,然后下完之后打開溪北,讓用戶自己安裝桐绒。wgt的生成需要在hbuilderx中操作(后續(xù)hbuilderx篇會講到),我們需要把wgt包上傳在服務(wù)器上之拨,前方偽代碼:

    uni.downloadFile({????url:?"wgt下載地址",    success: res => {      if (res.statusCode === 200) {        // 安裝wgt        plus.runtime.install(res.tempFilePath, {            force: false        }, function() {            // wgt安裝成功          if(silence){            uni.showToast({              title: "已更新最新的資源茉继,重啟應(yīng)用獲取更佳的用戶體驗",              duration: 4000,              icon: "none",              position: "bottom"            });          }else {            plus.runtime.restart();// 不是靜默升級,就立即重啟應(yīng)用          }        }, function(e) {          if(!silence){            downLoadFail();          }        });       }else {        downLoadFail();      }    },    fail: error => {      downLoadFail();    }  });

    細心的同學(xué)已經(jīng)發(fā)現(xiàn)了蚀乔,wgt安裝需要用戶重啟烁竭,否則不會生效。所以我們在開發(fā)中會有一個silence的選項吉挣,如果是true那么會選擇靜默更新(用戶無感知)這個時候我們只需要install安裝即可派撕,如果不是無感知婉弹,那么需要自動重啟。

    APP自定義tabbar

    我們在企業(yè)級開發(fā)中终吼,總會有一些沙雕產(chǎn)品想這種 “凸起”或者“奇奇怪怪”的tabbar(希望我司產(chǎn)品不會看到)事實上镀赌,這種自定義tabbar對于uniapp開發(fā)者來說,是有一定的難度际跪,首先如果是完全定制商佛,那么需要有較強的webview功底或者subnvue功底。

    由于自定義tabbar代碼較多垫卤,我們可以借助一些插件來實現(xiàn)威彰,但是值得注意的事情是,如果自定義tabbar在每一個頁面都引用穴肘,會出現(xiàn)抖動閃爍的問題歇盼,所以我們應(yīng)該在main.js中去draw這個tabbar

    Vue.prototype.$tabbarView?=?new?TabbarView();

    然后在每一個tabbar頁面去watch對應(yīng)的路徑變化,然后改變當前選中是第幾項item

    onShow(){  // #ifdef APP-PLUS  this.$tabbarView.$watch();  // #endif},onHide() {  // #ifdef APP-PLUS  this.$tabbarView.$watch();  // #endif},

    這個watch等方法评抚,是目前我司使用的組件的API豹缀,所以具體的定制tabbar思路知道了,我們使用一些第三方插件慨代,可以盡量少踩一些坑邢笙。

    引入原生安卓/IOS插件

    ios/安卓原生的插件我們可以在【插件市場】(之后會講到) 中找到,我們在manifest.json配置本地插件即可侍匙,那么具體的插件的添加辦法氮惯,如果是在插件市場直接點擊添加到APP中。

    如果我們是云打包(之后會說到這個概念)那么建議大家去社區(qū)直接購買然后添加想暗,在配置文件中選中即可妇汗。

    const?PluginName?=?uni.requireNativePlugin(PluginName);

    此API只存在于APP端,所以需要條件編譯说莫,傳入插件名稱杨箭,就會在對應(yīng)的APP中找已添加的插件是否存在(如果不懂這塊,可以看下面一篇說明:《manifest.json:uniapp的半壁江山》)储狭,如果插件已被添加則正常使用互婿。

    我們這邊實例選用的是uniapp官方文檔中的demo例子,插件是官方提供的原生增強提示框:

    const?dcRichAlert?=?uni.requireNativePlugin('DCloud-RichAlert')dcRichAlert.show({    position: 'bottom',    title: "提示信息",    titleColor: '#FF0000',    content: "<a  value='Hello uni-app'>uni-app</a> 是一個使用 Vue.js 開發(fā)跨平臺應(yīng)用的前端框架!\n免費的\n免費的\n免費的\n重要的事情說三遍",    contentAlign: 'left',    checkBox: {        title: '不再提示',        isSelected: true    },    buttons: [{        title: '取消'    }, {        title: '否'    }, {        title: '確認',        titleColor: '#3F51B5'    }]}, result => {    console.log(result)});

    說明一下引入原生插件的API辽狈,不管是vue還是nvue頁面都可以使用慈参。

    如果要debug,那么就必須重新打一個自定義基座包(下面會講到這個概念)否則不會生效刮萌。

    manifest.json:uniapp的半壁江山

    由于這個地方是uniapp配置項重中之重的地方懂牧,雖然用hbx直接預(yù)覽它會幫助我們自動格式化,但是可能我的解釋能讓這塊變得更簡單。

    app的ID是非常重要的僧凤,一般建立成功之后就不需要再更改畜侦,我們在注冊微信開放平臺,支付寶或者高德等等躯保,都需要用到APP的ID和包名(packageName)旋膳,包名設(shè)置會在之后介紹到

    ,基本設(shè)置中包含了幾個重要的信息途事,一個是應(yīng)用版本名稱一個是應(yīng)用版本號验懊,我們在做更新的時候需要+1,包括生成wgt包的時候尸变。

    我們可以在此處可視化的配置APP的模塊權(quán)限义图,那么uniapp封裝的模塊權(quán)限真的是傻瓜式的,配置一些平臺的key和secret然后再使用uniapp對應(yīng)的api即可召烂,那么肯定的事是這是增加包體積的碱工。

    引入原生插件,app如果有對應(yīng)特殊的業(yè)務(wù)需求也可以編譯原生的插件奏夫,具體如何引入本地原生插件怕篷,我們之前也提到過。

    剩余的配置都是針對于小程序/H5的配置酗昼,所以根據(jù)我們自己的業(yè)務(wù)可以自己去查詢文檔廊谓。

    uniapp應(yīng)該使用哪種請求庫呢?axios支持么麻削?

    uniapp是跨端框架蒸痹,為了迎合跨端,我們不可以使用axios呛哟,因為axios不支持APP原生端叠荠,它僅僅支持網(wǎng)頁端,所以我們可以使用uniapp提供的API(uni.request)一般這種API就夠用竖共,但是如果你想有像axios一樣的配置體驗的話,強烈建議你使用flyio.js 這個庫我們在新建項目時候會幫助我們安裝好的俺祠。

    uniapp項目是cli創(chuàng)建好還是hbx創(chuàng)建好公给?

    創(chuàng)建uniapp項目,可以分為2種模式:

    1.?cli命令行創(chuàng)建

    2. hbuilderX創(chuàng)建

    結(jié)論:優(yōu)先使用cli命令行創(chuàng)建蜘渣,因為對于開發(fā)vue web的人來說淌铐,cli命令行是最熟悉的,那么uniapp的cli方式創(chuàng)建的項目整體的目錄結(jié)構(gòu)類似于普通vue web項目蔫缸,而且我們直接使用npm快速安裝依賴腿准,像普通方式去引入;uniapp在版本支持上也是在cli項目上最先上線,可以使用cli體驗到最新的功能吐葱,對于初學(xué)者來說街望,標簽的學(xué)習是一個必須考慮進去的成本,cli方式創(chuàng)建的工程允許使用普通html標簽弟跑,比如<div><span><img>它們在編譯的時候會轉(zhuǎn)換成uniapp的標簽組件(盡管這樣寫并不推薦

    hbx創(chuàng)建的uniapp項目灾前,是隨著hbx軟件的版本升級而升級,cli創(chuàng)建的版本必須執(zhí)行

    npm update

    才能更新到最新版本孟辑,所以我建議大家搭建項目使用cli項目哎甲,在開發(fā)中使用uniapp的標簽不要使用html標簽。

    社區(qū)

    uniapp有著非乘撬裕活躍的社區(qū)炭玫,這是真的切身體驗過,使得整個開發(fā)遇到的問題我們都可以在社區(qū)找到(https://ask.dcloud.net.cn/)

    我們遇到了所有的bug貌虾,首選需要查詢是否是自身開發(fā)問題吞加,如果自測確認沒問題那么就可以在社區(qū)發(fā)布bug貼,如圖

    發(fā)布成功之后我們在文章底部邀請酝惧,輸入dcloud就可以邀請官方人員解答榴鼎,如果出現(xiàn)bug,也可以上傳代碼壓縮包(指定官方人員查看)這樣可以更快地讓官方找到問題幫助你解決問題晚唇。

    插件市場

    打一個廣告先巫财,我的UI庫的alpha版本在插件市場發(fā)布,盡管現(xiàn)在不開放下載哩陕,大概在年底左右會重構(gòu)給大家?guī)砀哔|(zhì)量的組件(名子叫 i-uniapp)希望大家關(guān)注一下

    https://ext.dcloud.net.cn/? 插件市場地址

    插件市場有很多vue組件/原生sdk等等平项,具體的安裝方法我們已經(jīng)在前面提到了,使用hbx開發(fā)uniapp項目可以直接點擊導(dǎo)入插件到項目中

    HbuilderX:開發(fā)uniapp神器(本文章重點)

    介紹Hbx和快速開發(fā)指南

    我可以很負責任的說悍及,雖然內(nèi)核是eclipse闽瓢,但是也算是國產(chǎn)的編輯器IDE,它在Vue的支持程度上足以讓我震驚心赶,說實話從Vue開發(fā)角度來說扣讼,HbuilderX比vscode好。但是hbx被吐槽地點也有很多缨叫,比如占用內(nèi)存高椭符,UI不如vscode/sublime等等,但是這是IDE之爭不在我們文章的討論重點之內(nèi)耻姥,所以我們?nèi)绻_發(fā)uniapp項目销钝,使用hbx開發(fā)是上上策

    我們?nèi)绻鞘褂胿scode或者sublime,可以在hbx調(diào)整快捷鍵語法

    插件安裝琐簇,我目前安裝的是這些蒸健,為了教程的順利和以后開發(fā)者的開發(fā)順利,請務(wù)必裝這幾個基礎(chǔ)插件。

    打包APP前的準備

    我們首先來看一下打包APP需要什么

    我們需要一個安卓證書似忧,我們來生成一下這個安卓證書

    1.? 首先需要安裝jdk渣叛,如果沒有jdk,就去安裝橡娄,然后在其bin文件夾下運行cmd

    keytool?-genkey?-alias?這里寫證書別名?-keyalg?RSA?-validity?36500?-keystore?這里寫證書名稱.keystore

    其中參數(shù)-validity為證書有效天數(shù)诗箍,我們可以寫的大寫。-alias后面是證書別名輸入密碼的時候沒有顯示挽唉,就輸入就行了滤祖。退格,tab等都屬于密碼內(nèi)容,這個密碼在給.apk文件簽名的時候需要瓶籽。輸入這個命令之后會提示您輸入秘鑰庫的口令接著是會提示你輸入:姓氏匠童,組織單?位名稱,組織名稱塑顺,城市或區(qū)域名稱汤求,省市,國家严拒、地區(qū)代碼扬绪,密鑰口令。確認正確輸入y裤唠,回車

    作者:草字頭烏君 鏈接:http://www.reibang.com/p/14add4a02ed6 來源:簡書

    keystore的密碼一定要記住挤牛,如果忘記需要執(zhí)行另外一個命令去查詢

    生成keystore成功之后我們可以在其bin目錄下發(fā)現(xiàn)一個以你設(shè)置為名字后綴為keystore文件

    2.? 填寫包名

    這個包名一般標準是以com開始的(java工程中的包名標準),ios不清楚,具體可以詢問具體的ios開發(fā)种蘸,命名包名是一個非常重要的事情墓赴,因為包名關(guān)系著一個APP的主要信息,在上架應(yīng)用商店的時候航瞭,包名則代表著APP的唯一性诫硕,所以一定要設(shè)置一個盡量貼合企業(yè)/個人的信息相關(guān)的名字,比如公司叫 “將進酒”:

    com.qiangjinjiu.andriod

    或者公司有具體的規(guī)定刊侯,則按照自身公司進行設(shè)置章办,這里就不闡述了

    3. 渠道包選項

    對應(yīng)的渠道包,可以在對應(yīng)的平臺做一個標識滨彻,可以在后臺看到每個平臺的使用指數(shù)藕届,這個根據(jù)業(yè)務(wù)需求可以打開,一般不會選擇

    4. 原生混淆

    可以對js和nvue文件進行原生混淆疮绷,提高安全性

    5. 廣告投放選擇

    uniapp自帶的廣告插件翰舌,根據(jù)業(yè)務(wù)需要自行選擇

    debug:自定義基座/小程序模擬器

    我們在上一段講解了如何打包APP嚣潜,打包APP之前的準備工作冬骚,那么細心的同學(xué)會發(fā)現(xiàn),打包APP中有這樣的一個選項

    什么是自定義基座,自定義基座是我們開發(fā)日常debug的包只冻,這個包沒有壓縮庇麦,所以會比正式包大,正式包記得選擇正式包不要選擇基座包喜德。自定義基座APP包安裝到手機上山橄,可以連接HbuilderX上,進行調(diào)試舍悯,下面介紹一下如何打自定義基座然后debug調(diào)試

    1. 云打包:發(fā)布之前的編譯階段

    2. 打包成功會返回成功信息航棱,自定義基座打包

    打包成功之后,我們拿起我們的諾基亞手機萌衬,打開usb調(diào)試模式(作為開發(fā)饮醇,如果連這個都不知道咋打開,那就去google吧)秕豫,調(diào)試模式打開之后朴艰,一定要選中hbx左邊的項目,然后點擊運行混移,運行手機模擬器祠墅,如圖(重點):

    基座選擇一定要選擇自定義基座(如果你沒打包自定義基座這里就沒有這個選項),然后等待手機歌径,會出現(xiàn)安裝基座(app)的提示毁嗦,點擊安裝,然后手機會自動打開APP沮脖,然后這個時候我們就可以更改代碼金矛,ui,然后手機及時更新變化勺届。

    那么debug自定義基座有什么注意事項呢驶俊?

    1. 當我們要調(diào)試登錄,分享免姿,地圖等具有原生權(quán)限功能的話饼酿,需要配置對應(yīng)平臺的key和secret。那么我們增加胚膊,修改了原生插件配置/原生插件的修改故俐,這個時候我們需要重新打包自定義基座查看最新的代碼。

    2. 切記不要把自定義基座當成正式包發(fā)布

    3. 不要打包打正式包debug紊婉,因為云打包正式包一天只有免費20次药版,我們debug用自定義基座就行了。

    那么我們覺得喻犁,日常的開發(fā)除了調(diào)試第三方登錄槽片,地圖等需要用手機去實際測試何缓,那么平時我們更改UI布局,難道也用自定義基座這么麻煩么还栓?

    答案是否定的碌廓,我們要知道,雖然布局UI在不同機型可能會產(chǎn)生偏差剩盒,但是我們?nèi)粘谷婆?梢允褂眯〕绦蚰M器進行開發(fā),然后開發(fā)完畢辽聊,在實體機型上進行初步測試纪挎,看看是否Ui或者功能有偏差,再具體更改跟匆,因為小程序模擬器是最接近APP的廷区,大部分UI布局功能都是最貼近用戶手機的。

    那么使用小程序模擬器調(diào)試贾铝,這里也有一些注意事項隙轻,我們?nèi)绻\行項目到微信小程序,如果是第一次垢揩,我們需要提前在小程序模擬器中的安全打開RFC調(diào)用

    設(shè)置->安全->端口開啟

    然后此時我們可以使用hbx來啟動微信小程序進行開發(fā)啦玖绿。

    APP打包

    我們項目模塊迭代開發(fā)之后,需要打包成APP叁巨,那么我們有2種途徑打包

    1. 云打包

    2. 離線打包

    以及特殊的wgt資源包(對應(yīng)之前提到的wgt更新)

    首先我們來說一下云打包斑匪,云打包是dcloud提供的云打包服務(wù)器,我們在客戶端HBX編譯之后就會進入云打包的隊列锋勺,由dcloud打包服務(wù)器打包成功之后返回給hbx控制臺臨時的下載鏈接蚀瘸。

    那么在之前,我們已經(jīng)了解了自定義基座庶橱,那么這個自定義基座的打包和云打包(正式包)只是一個選項的問題贮勃,云打包每天有20次的免費機會,所以切記我們debug千萬不要生成線上包

    離線打包指的是我們可以把uniapp工程生成出原生工程苏章,由我們開發(fā)者自己去打包寂嘉,那么我相信如果有原生基礎(chǔ)的開發(fā)者會很樂意這樣做,但是務(wù)必提醒一點就是社區(qū)很多的問題都是離線打包造成的枫绅,那么為了更穩(wěn)定的APP開發(fā)泉孩,我建議使用云打包。

    我們在之前提到的wgt資源包并淋,我們應(yīng)該這樣生成寓搬,生成成功的wgt資源包上傳到服務(wù)器,然后按照前面的demo進行更新

    關(guān)于IOS

    其實關(guān)于IOS县耽,本人并不是了解很多句喷,我可以簡單講一下曼尊,可能對于新手很重要。

    1. uniapp的應(yīng)用是可以被審核成功的脏嚷,因為19年年底蘋果發(fā)了一則通知,大概是性能差勁的套殼APP不會被上架瞒御,但是2020年父叙,必須知道uniapp不是套殼APP,它也有原生宣傳肴裙,webview渲染性能也是非常強勁的趾唱,沒有網(wǎng)上說的那么不堪。

    2. 如果是windows用戶那么我建議你使用mac開發(fā)uniapp蜻懦,因為windows開發(fā)打包出的ios包不太方便去上架等等甜癞,而mac系統(tǒng)沒有這個顧慮。

    3. windows新手如果沒有上架過宛乃,可以在windows下載Application Loader, 如果是mac用戶那么強烈推薦你下載Transporter App 悠咱,老司機就用xcode內(nèi)置的上傳吧~

    拓展閱讀

    1. uniapp統(tǒng)計功能,免費征炼,安全析既,統(tǒng)計數(shù)據(jù)非常詳細,支持自定義埋點谆奥。

    https://#dcloud.net.cn/

    2. uniapp云開發(fā)眼坏,現(xiàn)在云開發(fā),云數(shù)據(jù)庫這么火酸些,早在幾年前小程序就有這樣的東西宰译,云開發(fā)也是今年uniapp非常大的更新,現(xiàn)在支持騰訊云和阿里云魄懂,據(jù)說還比較便宜沿侈,感興趣的小伙伴可以去看看。

    https://unicloud.dcloud.net.cn/login

    3. uniapp廣告平臺市栗,非常適用于個人肋坚,個人做的APP可以通過這個廣告平臺變現(xiàn)。

    https://uniad.dcloud.net.cn/login

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    • 序言:七十年代末肃廓,一起剝皮案震驚了整個濱河市智厌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盲赊,老刑警劉巖铣鹏,帶你破解...
      沈念sama閱讀 207,113評論 6 481
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哀蘑,居然都是意外死亡诚卸,警方通過查閱死者的電腦和手機葵第,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 88,644評論 2 381
    • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來合溺,“玉大人卒密,你說我怎么就攤上這事√娜” “怎么了哮奇?”我有些...
      開封第一講書人閱讀 153,340評論 0 344
    • 文/不壞的土叔 我叫張陵,是天一觀的道長睛约。 經(jīng)常有香客問我鼎俘,道長,這世上最難降的妖魔是什么辩涝? 我笑而不...
      開封第一講書人閱讀 55,449評論 1 279
    • 正文 為了忘掉前任贸伐,我火速辦了婚禮,結(jié)果婚禮上怔揩,老公的妹妹穿的比我還像新娘捉邢。我一直安慰自己,他們只是感情好商膊,可當我...
      茶點故事閱讀 64,445評論 5 374
    • 文/花漫 我一把揭開白布歌逢。 她就那樣靜靜地躺著,像睡著了一般翘狱。 火紅的嫁衣襯著肌膚如雪秘案。 梳的紋絲不亂的頭發(fā)上,一...
      開封第一講書人閱讀 49,166評論 1 284
    • 那天潦匈,我揣著相機與錄音阱高,去河邊找鬼。 笑死茬缩,一個胖子當著我的面吹牛赤惊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凰锡,決...
      沈念sama閱讀 38,442評論 3 401
    • 文/蒼蘭香墨 我猛地睜開眼未舟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掂为?” 一聲冷哼從身側(cè)響起裕膀,我...
      開封第一講書人閱讀 37,105評論 0 261
    • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎勇哗,沒想到半個月后昼扛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
      沈念sama閱讀 43,601評論 1 300
    • 正文 獨居荒郊野嶺守林人離奇死亡欲诺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點故事閱讀 36,066評論 2 325
    • 正文 我和宋清朗相戀三年抄谐,在試婚紗的時候發(fā)現(xiàn)自己被綠了渺鹦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
      茶點故事閱讀 38,161評論 1 334
    • 序言:一個原本活蹦亂跳的男人離奇死亡蛹含,死狀恐怖毅厚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浦箱,我是刑警寧澤吸耿,帶...
      沈念sama閱讀 33,792評論 4 323
    • 正文 年R本政府宣布,位于F島的核電站憎茂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锤岸。R本人自食惡果不足惜竖幔,卻給世界環(huán)境...
      茶點故事閱讀 39,351評論 3 307
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望是偷。 院中可真熱鬧拳氢,春花似錦、人聲如沸蛋铆。這莊子的主人今日做“春日...
      開封第一講書人閱讀 30,352評論 0 19
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽刺啦。三九已至留特,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玛瘸,已是汗流浹背蜕青。 一陣腳步聲響...
      開封第一講書人閱讀 31,584評論 1 261
    • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糊渊,地道東北人右核。 一個月前我還...
      沈念sama閱讀 45,618評論 2 355
    • 正文 我出身青樓,卻偏偏與公主長得像渺绒,于是被迫代替她去往敵國和親贺喝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
      茶點故事閱讀 42,916評論 2 344