前端跨平台框架
之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在開發者數量、案例、靈活性、生態、開發成本等關鍵指標上有一定優勢,能夠滿足大部分的基礎需求,就學習成本而言,較容易上手,也為前端開發者提供了更多的可能,值得推薦。當然,任何框架都首先要服務於實際業務需求,技術的選型也需根據研發團隊成員的技術方向和具體情況而定,對於項目建設而言技術框架沒有最好的只有最適合的。
以上僅是我自己的一孔之見,這里拋磚引玉,歡迎大家積極交流意見和建議,共同學習和進步,謝謝大家!