前端跨平臺框架
之uniapp入門淺析
技術的發展總日新月異,處在風口,前端技術的發展尤為迅速,跨平臺的概念也在前端流行起來。從最早期PhoneGap、lonic、Cordova,到近年來的ReactNative、weex、flutter,前端開發者在跨平臺方面的探索從未停止過。趨勢使然,類似uniapp框架出現在前端技術圈是技術發展潮流下的必然產物。作者自己也對uniapp框架進行了探索和實踐,下面從幾個方面介紹這一框架及其用法,歡迎大家踴躍討論
一、什麼是 uni-app?
uni-app 這個框架是基於Vue.js開發的,通過uni-app可以開發出跨平臺的產品,所以如果對vue有一定的瞭解,那麼這套框架可以很快速的掌握,當然,如果你對微信小程式也瞭解的話,也能夠迅速掌握的,因為Uni-App封裝並且相容了微信小程式的元件和api。開發者編寫一套程式碼,可釋出到iOS、Android、Web(響應式)、以及各種小程式(微信/支付寶/百度/頭條/QQ/釘釘/淘寶)、快應用等多個平臺。
二、為什麼要選擇uni-app?
對比其他移動端跨平臺框架(如Cordova/ReactNative/NativeJS),UniApp在跨端抹平度、擴充套件靈活性、效能體驗、周邊生態、開發成本等幾個方面上擁有明顯的優勢。
(1)跨端數量多:一套程式碼,編譯後可釋出到iOS、Android、H5、小程式等多個平臺,且跨端抹平度高,應用的顯示效果接近一致,真正能落實到生產力。這一點是uniapp的最大優勢,完勝其他跨平臺框架。
(2)效能體驗優秀:uniapp是體驗更好的Hybrid框架,載入新頁面速度更快。且App端支援weex原生渲染,可實現更流暢的動畫效果。相比較而言,依賴於WebView的Cordova框架效能方面就有所欠缺了。
(3)生態開放豐富:uniapp的外掛市場,集成了近千餘第三方外掛,各種輪子拿來即用;同時,由於uniapp的介面API採用了小程式規範,微信生態的各種SDK可直接用於跨平臺App。在這個方面作對比,React Native框架的社群活躍度和資料文件都較為有限。
(4)開發成本低:以前由N個平臺開發人員(IOS/安卓/H5)完成的開發任務,現在採用前端通用技術棧實現,研發、維護、測試各環節的成本都大幅下降。
同時,HBuilderX工具搭配uniapp可以免終端除錯,視覺化建立專案、視覺化安裝元件和擴充套件編譯器,研發人員的開發體驗也變得更好,從而能夠更高效地編寫程式碼。
三、uniapp發展史
uni是統一的意思。
很多人以為小程式是微信先推出的,其實,DCloud才是這個行業的開創者。
DCloud於2012年開始研發小程式技術,優化webview的功能和效能,並加入W3C和HTML5中國產業聯盟,推出了HBuilder開發工具,為後續產業化做準備。
2015年,DCloud正式商用了自己的小程式,產品名為“流應用”,它不是B/S模式的輕應用,而是能接近原生功能、效能的動態App,並且即點即用。
為將該技術發揚光大,DCloud將技術標準捐獻給工信部旗下的HTML5中國產業聯盟,並推進各家流量巨頭接入該標準,開展小程式業務。
隨後DCloud推動大眾點評、攜程、京東、有道詞典、唯品會等眾多開發者為流應用平臺提供應用。
在2015年9月,DCloud推進微信團隊開展小程式業務,演示了流應用的秒開應用、掃碼獲取應用、分享連結獲取應用等眾多場景案例,以及分享了webview體驗優化的經驗。
微信團隊經過分析,於2016年初決定上線小程式業務,但其沒有接入聯盟標準,而是訂製了自己的標準。
DCloud持續在業內普及小程式理念,推進各大流量巨頭,包括手機廠商,陸續上線類似小程式/快應用等業務。
部分公司接入了聯盟標準,但更多公司因利益紛爭嚴重,標準難以統一。
技術是純粹的,不應該因為商業利益而分裂。開發者面對如此多的私有標準不是一件正確的事情。
造成混亂的局面非DCloud所願。於是就決定開發一個免費開源的框架。
既然各巨頭無法在標準上達成一致,官方希望通過這個框架為開發者抹平各平臺差異。這就是uni-app的由來。
四、功能框架
下面是uni-app功能框架圖,圖中直觀的表現了uniapp出色的跨平臺能力和各平臺特色。不多說,直接上圖:
從上面uni-app功能框架圖可看出,uni-app在跨平臺的過程中,不犧牲平臺特色,可優雅的呼叫平臺專有能力。用官方的話說就是:海納百川、各取所長。
概念匯入:
- (1)什麼是H5+?
HTML5plus Runtime,簡稱5+ Runtime,是運行於手機端的強化web引擎,除了支援標準HTML5外,還支援更多擴充套件的js api,使得js的能力不輸於原生。5+ Runtime內置於HBuilder,在真機執行、打包時自動掛載。
業內之前有phonegap/Cordova方案,但是他們自帶js api太少了,擴充套件api需要用原生語言開發,更致命的是這類方案的效能不足。
封裝成跨平臺的HTML5plus規範,並將規範公開於www.HTML5plus.org,不做廠商私有API。包括二維碼、搖一搖、語音輸入、地圖、支付、分享、檔案系統、通訊錄等常用API,可以方便簡單的編寫,並且可跨平臺。
注意:uni-app不需要 plus ready
在html中使用plus的api,需要等待plus ready。 而uni-app不需要等,可以直接使用。而且如果你呼叫plus ready,反而不會觸發。
小程式及 H5 等平臺是沒有 HTML5+ 擴充套件規範的,因此在 uni-app 呼叫 HTML5+ 的擴充套件規範時,需要注意使用條件編譯。否則執行到h5、小程式等平臺會出現 plus is not defined錯誤。
- (2)什麼是條件編譯?
條件編譯是用特殊的註釋作為標記,在編譯時根據這些特殊的註釋,將註釋裡面的程式碼編譯到不同平臺。
寫法:以 #ifdef 或 #ifndef 加 %PLATFORM% 開頭,以 #endif 結尾。
- · #ifdef:if defined 僅在某平臺存在
- · #ifndef:if not defined 除了某平臺均存在
- · %PLATFORM%:平臺名稱
條件編譯寫法 |
說明 |
#ifdef APP-PLUS |
僅出現在 App 平臺下的程式碼 |
#ifndef H5 |
除了 H5 平臺,其它平臺均存在的程式碼 |
#ifdef H5 || MP-WEIXIN |
在 H5 平臺或微信小程式平臺存在的程式碼(這裡只有||,不可能出現&&,因為沒有交集) |
%PLATFORM% 可取值如下:
值 |
平臺 |
APP-PLUS |
App |
APP-PLUS-NVUE或APP-NVUE |
App nvue |
H5 |
H5 |
MP-WEIXIN |
微信小程式 |
MP-ALIPAY |
支付寶小程式 |
MP-BAIDU |
百度小程式 |
MP-TOUTIAO |
位元組跳動小程式 |
MP-QQ |
QQ小程式 |
MP-360 |
360小程式 |
MP |
微信小程式/支付寶小程式/百度小程式/位元組跳動小程式/QQ小程式/360小程式 |
QUICKAPP-WEBVIEW |
快應用通用(包含聯盟、華為) |
QUICKAPP-WEBVIEW-UNION |
快應用聯盟 |
QUICKAPP-WEBVIEW-HUAWEI |
快應用華為 |
注意:
- · 條件編譯是利用註釋實現的,在不同語法裡註釋寫法不一樣,js使用 // 註釋、css 使用 /* 註釋 */、vue/nvue 模板裡使用 <!-- 註釋 -->;
- · 條件編譯APP-PLUS包含APP-NVUE和APP-VUE,APP-PLUS-NVUE和APP-NVUE沒什麼區別,為了簡寫後面出了APP-NVUE ;
API 的條件編譯
// #ifdef %PLATFORM%
平臺特有的API實現
// #endif
- (3)什麼是nvue?
uni-app App端內建了一個基於 weex 改進的原生渲染引擎,提供了原生渲染能力。
在App端,如果使用vue頁面,則使用webview渲染;如果使用nvue頁面(native vue的縮寫),則使用原生渲染。一個App中可以同時使用兩種頁面,比如首頁使用nvue,二級頁使用vue頁面。
注意:雖然nvue也可以多端編譯,輸出H5和小程式,但nvue的css寫法受限,所以如果你不開發App,那麼不需要使用nvue。
- (4)Uniapp編譯模式是怎樣的?
最初uni-app僅支援模板編譯模式和自定義元件模式,在後來的升級中逐漸用V3編譯模式取代,v3是針對App的改進,尤其是vue頁面的改進。與其他平臺無關。目前V3已成為預設的編譯模式。此外uni-app還支援對nvue編譯模式的選擇,分為weex編譯模式和uni-app編譯模式,這裡不做詳細解讀,有興趣的同學可以自行學習。
五. 如何使用uni-app?
(1) 下載開發工具:HBuilderX
開啟dcloud官網 http://www.dcloud.io/hbuilderx.html 推薦直接下載App開發版本,可以免去後續配置及安裝外掛等的煩惱
(2) 安裝並開啟HBuilderX
之後,在點選工具欄裡的檔案 -> 新建 -> 專案
- (3) 選擇uni-app,輸入工程名,如:uni-test,點選建立,成功建立 UniApp應用。點選模板裡的 Hello uni-app 即可體驗官方示例。
- (4) 隨著官方的不斷迭代升級,現已支援建立多套模板,可以便捷的搭建專案框架,已內建大量常用元件,免去了搭建專案的大部分前期工作,這點非常方便。如下是 uni ui專案模板的常見例子,供大家參考。
(4)建立DCloud appid(以後簡稱 appid)。appid是 DCloud 應用的唯一標識,在 DCloud 提供的所有服務中,都會以 appid 來標記一個應用。注意這和各家小程式的appid以及Apple的appid(其實就是iOS的包名)是兩套體系。
- l 登入開發者中心,申請建立 uniapp、5+app 等型別應用的 appid;
- l 在 HBuilderX登入的情況下, 建立專案時,HBuilderX 也會自動聯網生成 appid, 並將該 appid 儲存在 manifest 檔案中的 appid 欄位;
(5)工程目錄結構
(6)進入專案,點選工具欄的執行 -> 執行到瀏覽器/真機下執行/模擬器執行,也可以選擇小程式在微信開發者工具裡執行,如下是專案執行的示例。
瀏覽器執行:進入hello-uniapp專案,點選工具欄的執行 -> 執行到瀏覽器 -> 選擇瀏覽器,即可在瀏覽器裡面體驗uni-app 的 H5 版。
真機執行:連線手機,開啟USB除錯,進入hello-uniapp專案,點選工具欄的執行 -> 真機執行 -> 選擇執行的裝置,即可在該裝置裡面體驗uni-app。
如手機無法識別,請點選選單執行-執行到手機或模擬器-真機執行常見故障排查指南。 注意開發App也需要安裝微信開發者工具。
(7)釋出uni-app
Unapp有兩種釋出形式:打包為原生App(雲端)和打包為原生App(離線)。由於離線打包需要一定原生基礎,且sdk不能隨官方升級,實時更新,一般採用app-雲端打包的形式。
在HBuilderX工具欄,點擊發行,選擇原生app-雲端打包,如下圖:
出現如下介面,點選打包即可。
打包為原生App(離線)
uni-app 支援離線打包,在 HBuilderX 發行選單裡生成離線打包資源,然後參考離線打包文件操作,可以從HBuilderX的發行選單裡找到文件連結,也可以直接訪問:https://nativesupport.dcloud.net.cn/AppDocs/README。
在HBuilderX工具欄,點擊發行,選擇本地打包,如下圖,點選即可生成離線打包資源。
釋出為H5
- 1. 在 manifest.json 的視覺化介面,進行如下配置(發行在網站根目錄可不配置應用基本路徑),此時發行網站路徑是 www.xxx.com/h5,如:https://hellouniapp.dcloud.net.cn。
- 2. 在HBuilderX工具欄,點擊發行,選擇網站-H5手機版,如下圖,點選即可生成 H5 的相關資原始檔,保存於 unpackage 目錄。
注意
- l history 模式發行需要後臺配置支援。
- l 打包部署後,在伺服器上開啟 gzip 可以進一步壓縮檔案。
釋出為小程式
釋出為微信小程式:
- 1. 申請微信小程式AppID,參考:微信教程。
- 2. 在HBuilderX中頂部選單依次點選 "發行" => "小程式-微信",輸入小程式名稱和appid點擊發行即可在 unpackage/dist/build/mp-weixin 生成微信小程式專案程式碼。
- 3. 在微信小程式開發者工具中,匯入生成的微信小程式專案,測試專案程式碼執行正常後,點選“上傳”按鈕,之後按照 “提交稽核” => “釋出” 小程式標準流程,逐步操作即可,詳細檢視:微信官方教程。
六、開發規範
(1)頁面檔案 遵循Vue單頁面元件規範,Vue中的結構依然採用三大頂級程式碼塊:vue-loader規範
(2)元件標籤 VUE通用模板寫法,編譯後以IOS或Android原生UI控制元件渲染
(所以不能使用標準的HTML標籤,JS對DOM操作也得儘量避免),示例:
- (3)介面能力: 基本遵循微信小程式規範,對於大部分介面地址字首由wx修改為uni即可實現,也包括了uni特有的一些api,具體參考:https://uniapp.dcloud.io/api/README
隨著severless的發展,uniapp還提供了基於unicloud的雲函式、雲資料庫、雲端儲存和CDN方案,uniCloud 是 DCloud 聯合阿里雲、騰訊雲,為開發者提供的基於 serverless 模式和 js 程式設計的雲開發平臺。
此外,uniapp還提供了了很多
- (4)樣式控制:
uni-app 支援通用 css 單位包括 px;另外,針對螢幕寬度自適應的普遍需求,推出了響應式px的概念,最初,uniapp以upx為尺寸單位,在框架的升級過程中,借鑑了微信小程式rpx的設計理念,轉為rpx。
rpx 是相對於基準寬度的單位,可以根據螢幕寬度進行自適應。uni-app 規定螢幕基準寬度 750rpx。
開發者可以通過設計稿基準寬度計算頁面元素 rpx 值,設計稿 1px 與框架樣式 1rpx 轉換公式如下:
設計稿 1px / 設計稿基準寬度 = 框架樣式 1rpx / 750rpx
換言之,頁面元素寬度在 uni-app 中的寬度計算公式:
750 * 元素在設計稿中的寬度 / 設計稿基準寬度
(5)uniapp開發與傳統前端開發的異同點:
傳統的h5只有1端,即瀏覽器。而uni-app可跨多端,雖仍屬前端,與傳統h5有不同。
網路模型的變化
以前網頁大多是b/s,服務端程式碼混合在頁面裡;
現在是c/s,前後端分離,通過js api(類似ajax的uni.request)獲取json資料,把資料繫結在介面上渲染。
檔案型別變化
以前是.html檔案,開發也是html,執行也是html。
現在是.vue檔案,開發是vue,經過編譯後,執行時已經變成了js檔案。
現代前端開發,很少直接使用HTML,基本都是開發、編譯、執行。所以uni-app有編譯器、執行時的概念。
檔案內程式碼架構的變化
以前一個html大節點,裡面有script和style節點;
現在template是一級節點,用於寫tag元件,script和style是並列的一級節點,也就是有3個一級節點。
外部檔案引用方式變化
以前通過script src、link href引入外部的js和css;
現在是es6的寫法,import引入外部的js模組(注意不是檔案)或css
示例
var dateUtils = require('../../../common/util.js').dateUtils; //直接使用js模組的屬性。在hello uni-app有示例
import * as echarts from '/components/echarts/echarts.simple.min.js'; //將js匯入並重命名為echarts,然後使用echarts.來繼續執行方法。在hello uni-app有示例
css外部檔案匯入
<style>
@import "./common/uni.css";
.uni-hello-text{
color:#7A7E83;
}
</style>
全域性樣式,在根目錄下的app.vue裡寫入,每個頁面都會載入app.vue裡的樣式。
另外,vue支援元件匯入,可以更方便的封裝一個包括介面、js、樣式的庫。
如下是匯入一個角標的元件庫,在頁面上顯示一個abc並且右上角有個數字角標1,
<template>
<view>
<uni-badge text="abc" :inverted="true"></uni-badge><!--3.使用元件-->
</view>
</template>
<script>
import uniBadge from "../../../components/uni-badge.vue";//1.匯入元件(這步屬於傳統vue規範,但在uni-app的easycom下可以省略這步)
export default {
data() {
return {
}
},
components: {
uniBadge //2.註冊元件(這步屬於傳統vue規範,但在uni-app的easycom下可以省略這步)
}
}
</script>
如需要全域性匯入vue元件,即每個頁面都可以直接使用而不用引用和註冊的話,在專案根目錄下的main.js裡處理。
元件/標籤的變化
以前是html標籤,比如<div>,現在是小程式元件,比如<view>。
那麼標籤和元件有什麼區別,不都是用尖括號包圍起來一段英文嗎?
其實標籤是老的概念,標籤屬於瀏覽器內建的東西。但元件,是可以自由擴充套件的。
類似你可以把一段js封裝成函式或模組,你也可以把一個ui控制元件封裝成一個元件。
uni-app參考小程式規範,提供了一批內建元件。
下為html標籤和uni-app內建元件的對映表:
- § div 改成 view
- § span、font 改成 text
- § a 改成 navigator
- § img 改成 image
- § input 僅僅是輸入框。 原html規範中input不僅是輸入框,還有radio、checkbox、時間、日期、檔案選擇功能。在uni-app和小程式規範中,input僅僅是輸入框。其他功能uni-app有單獨的元件或API:radio元件、checkbox元件、時間選擇、日期選擇、圖片選擇、視訊選擇、多媒體檔案選擇(含圖片視訊)、通用檔案選擇。
- § form、button、label、textarea、canvas、video 這些還在。
- § select 改成 picker
- § iframe 改成 web-view
- § ul、li沒有了,都用view替代。做列表一般使用uList元件
- § audio 不再推薦使用,改成api方式,背景音訊api文件
其實老的HTML標籤也可以在uni-app裡使用,uni-app編譯器會在編譯時把老標籤轉為新標籤,比如把div編譯成view。但不推薦這種用法,除錯H5端時容易混亂。
除了改動外,新增了一批手機端常用的新元件
- § scroll-view 可區域滾動檢視容器
- § swiper 可滑動區域檢視容器
- § icon 圖示
- § rich-text 富文字(不可執行js,但可渲染各種文字格式和圖片)
- § progress 進度條
- § slider 滑塊指示器
- § switch 開關選擇器
- § camera 相機
- § live-player 直播
- § map 地圖
- § cover-view 可覆蓋原生元件的檢視容器
cover-view需要多強調幾句,uni-app的非h5端的video、map、canvas、textarea是原生元件,層級高於其他元件。如需覆蓋原生元件,則需要使用cover-view元件。詳見層級介紹
除了內建元件,還有很多開源的擴充套件元件,把常用操作都進行封裝,DCloud建立了外掛市場收錄這些擴充套件元件,詳見外掛市場
js的變化
js的變化,分為執行環境變化、資料繫結模式變化、api變化3部分。
執行環境從瀏覽器變成v8引擎
標準js語法和api都支援,比如if、for、settimeout、indexOf等。
但瀏覽器專用的window、document、navigator、location物件,包括cookie等儲存,只有在瀏覽器中才有,app和小程式都不支援。
js是ECMAScript組織管理的,瀏覽器中的js是w3c組織基於js規範補充了window、document、navigator、location等專用物件。
在uni-app的各個端中,除了h5端,其他端的js都執行在一個獨立的v8引擎下,不是在瀏覽器中,所以瀏覽器的物件無法使用。如果你做過小程式開發,對此應當很瞭解。
這意味著依賴document的很多HTML的庫,比如jqurey無法使用。
當然app和小程式支援web-view元件,裡面可以載入標準HTML,這種頁面仍然支援瀏覽器專用物件window、document、navigator、location。
uni-app使用vue的資料繫結方式解決js和dom介面互動的問題。
在普通vue頁面裡的生命週期叫頁面生命週期。在專案根目錄的app.vue檔案中的生命週期叫應用生命週期。
除了onload,還有onready等很多生命週期,具體見uni-app的生命週期
js api的變化
- § 因為uni-app的api是參考小程式的,所以和瀏覽器的js api有很多不同,如
- § alert,confirm 改成 uni.showmodel
- § ajax 改成 uni.request
- § cookie、session 沒有了,local.storage 改成 uni.storage
- § uni-app的js api還有很多,但基本就是小程式的api,把wx.xxx改為uni.xxx即可。
css的變化
- § 標準的css基本都是支援的。
- § 選擇器有2個變化:*選擇器不支援;元素選擇器裡沒有body,改為了page。微信小程式即是如此。
page{
}
注意css裡背景圖和字型檔案,儘量不要大於40k,因為會影響效能。在小程式端,如果要大於40k,需放到伺服器側遠端引用或base64後引入,不能放到本地作為獨立檔案引用。
工程結構和頁面管理
uni-app的工程結構有單獨的要求,上面例子中有講到過:
每個可顯示的頁面,都必須在 pages.json 中註冊。如果你開發過小程式,那麼pages.json類似app.json。如果你熟悉vue,這裡沒有vue的路由,都是在pages.json裡管理。
原來工程的首頁一般是index.html或default.html,是在web server裡配的。而uni-app的首頁,是在pages.json裡配的,page節點下第一個頁面就是首頁。一般在/pages/xx的目錄下。
app和小程式中,為了提升體驗,頁面提供了原生的導航欄和底部tabbar,注意這些配置是在pages.json中做,而不是在vue頁面裡建立。如果你熟悉小程式開發的話,對比變化如下:
- § 原來app.json被一拆為二。頁面管理,被挪入了uni-app的pages.json;非頁面管理,挪入了manifest.json
- § 原來的app.js和app.wxss被合併到了app.vue中
七、uni-app基本原理
技術的發展日新月異,各項新技術、新概念層出不窮。隨著“微前端”理念發展,特別是微信小程式技術的“後發先至”,加速了uni-app的推出程序。結合實際專案中的使用分析來看,uniapp的實現更應該是檔案預處理、編譯技術和架構理念的更新,隨著微信小程式的廣為人知,及各家小程式的相互“借鑑”,uniapp迎合了這一趨勢,為更好的發揮“流應用”框架的跨平臺的能力,因此採用了近似小程式的專案架構。
實際上,不管是就跨平臺、適配、還是條件編譯等等,類比webpack預編譯的實現方式和vue框架在vue-loader上的處理方式,我們不難理解uniapp在各平臺先編譯後執行的基本原理,其最終目的都是通過後期的編譯,來實現各端在規範和格式上的統一。
- 八、擴充套件能力和開發生態
uniapp支援混和開發和uni小程式開發。uni-app 積極擁抱社群,建立了開放、相容的生態系統。
總結
uni-app從誕生至今,經過了uni官方和廣大開發者長時間的打磨過程,“野蠻生長”的洪荒時代業已成為過去,如今,使用uni-app 在UI表現力、效能體驗、生態成熟度幾個維度都能經得起推敲。發展到現在,即便框架本身有著低成本的特性,uni-app仍然是一套相對完整的體系,還有很多方面很難一言蔽之。
綜合來講,uni-app在開發者數量、案例、靈活性、生態、開發成本等關鍵指標上有一定優勢,能夠滿足大部分的基礎需求,就學習成本而言,較容易上手,也為前端開發者提供了更多的可能,值得推薦。當然,任何框架都首先要服務於實際業務需求,技術的選型也需根據研發團隊成員的技術方向和具體情況而定,對於專案建設而言技術框架沒有最好的只有最適合的。
以上僅是我自己的一孔之見,這裡拋磚引玉,歡迎大家積極交流意見和建議,共同學習和進步,謝謝大家!