https://uniapp.dcloud.io/platform
跨端兼容
uni-app 已將常用的組件、JS API 封裝到框架中,開發者按照 uni-app 規范開發即可保證多平台兼容,大部分業務均可直接滿足。
但每個平台有自己的一些特性,因此會存在一些無法跨平台的情況。
- 大量寫 if else,會造成代碼執行性能低下和管理混亂。
- 編譯到不同的工程后二次修改,會讓后續升級變的很麻煩。
在 C 語言中,通過 #ifdef、#ifndef 的方式,為 windows、mac 等不同 os 編譯不同的代碼。 uni-app
參考這個思路,為 uni-app
提供了條件編譯手段,在一個工程里優雅的完成了平台個性化實現。
條件編譯
條件編譯是用特殊的注釋作為標記,在編譯時根據這些特殊的注釋,將注釋里面的代碼編譯到不同平台。
寫法:以 #ifdef 或 #ifndef 加 %PLATFORM% 開頭,以 #endif 結尾。
- #ifdef:if defined 僅在某平台存在
- #ifndef:if not defined 除了某平台均存在
- %PLATFORM%:平台名稱
條件編譯寫法 | 說明 |
---|---|
#ifdef APP-PLUS 需條件編譯的代碼 #endif | 僅出現在 App 平台下的代碼 |
#ifndef H5 需條件編譯的代碼 #endif | 除了 H5 平台,其它平台均存在的代碼 |
#ifdef H5 || MP-WEIXIN 需條件編譯的代碼 #endif | 在 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 | 快應用華為 |
支持的文件
- .vue
- .js
- .css
- pages.json
- 各預編譯語言文件,如:.scss、.less、.stylus、.ts、.pug
注意:
- 條件編譯是利用注釋實現的,在不同語法里注釋寫法不一樣,js使用
// 注釋
、css 使用/* 注釋 */
、vue/nvue 模板里使用<!-- 注釋 -->
; - 條件編譯APP-PLUS包含APP-NVUE和APP-VUE,APP-PLUS-NVUE和APP-NVUE沒什么區別,為了簡寫后面出了APP-NVUE ;
API 的條件編譯
// #ifdef %PLATFORM%
平台特有的API實現
// #endif
示例,如下代碼僅在 App 下出現:
示例,如下代碼不會在 H5 平台上出現:
除了支持單個平台的條件編譯外,還支持多平台同時編譯,使用 || 來分隔平台名稱。
示例,如下代碼會在 App 和 H5 平台上出現:
組件的條件編譯
<!-- #ifdef %PLATFORM% -->
平台特有的組件
<!-- #endif -->
示例,如下公眾號關注組件僅會在微信小程序中出現:
<view>
<view>微信公眾號關注組件</view>
<view>
<!-- uni-app未封裝,但可直接使用微信原生的official-account組件-->
<!-- #ifdef MP-WEIXIN -->
<official-account></official-account>
<!-- #endif -->
</view>
</view>
樣式的條件編譯
/* #ifdef %PLATFORM% */
平台特有樣式
/* #endif */
注意: 樣式的條件編譯,無論是 css 還是 sass/scss/less/stylus 等預編譯語言中,必須使用 /*注釋*/
的寫法。
正確寫法
錯誤寫法
pages.json 的條件編譯
下面的頁面,只有運行至 App 時才會編譯進去。
不同平台下的特有功能,以及小程序平台的分包,都可以通過 pages.json 的條件編譯來更好地實現。這樣,就不會在其它平台產生多余的資源,進而減小包體積。
json的條件編譯,如不同平台的key名稱相同,cli項目下開發者自己安裝的校驗器會報錯,需自行關閉這些校驗器對json相同key的校驗規則。如果使用HBuilderX的校驗器,無需在意此問題,HBuilderX的語法校驗器為此優化過。
static 目錄的條件編譯
在不同平台,引用的靜態資源可能也存在差異,通過 static 的的條件編譯可以解決此問題,static 目錄下新建不同平台的專有目錄(目錄名稱同 %PLATFORM%
值域,但字母均為小寫),專有目錄下的靜態資源只有在特定平台才會編譯進去。
如以下目錄結構,a.png
只有在微信小程序平台才會編譯進去,b.png
在所有平台都會被編譯。
┌─static
│ ├─mp-weixin
│ │ └─a.png
│ └─b.png
├─main.js
├─App.vue
├─manifest.json
└─pages.json
整體目錄條件編譯
如果想把各平台的頁面文件更徹底的分開,也可以在uni-app項目根目錄創建platforms
目錄,然后在下面進一步創建app-plus
、mp-weixin
等子目錄,存放不同平台的文件。
注意
platforms
目錄下只支持放置頁面文件(即頁面vue文件),如果需要對其他資源條件編譯建議使用static 目錄的條件編譯
HBuilderX 支持
HBuilderX 為 uni-app
的條件編譯提供了豐富的支持:
代碼塊支持
在 HBuilderX 中開發 uni-app
時,通過輸入 ifdef 可快速生成條件編譯的代碼片段
語法高亮
在 HBuilderX 中對條件編譯的代碼注釋部分提供了語法高亮,可分辨出寫法是否正確,使得代碼更加清晰(獨立js文件需在編輯器右下角切換javascript es6+編輯器,獨立css文件暫不支持高亮,但不高亮不影響使用)
正確注釋和快速選中
在 HBuilderX 中,ctrl+alt+/ 即可生成正確注釋(js:// 注釋
、css:/* 注釋 */
、vue/nvue模板: <!-- 注釋 -->
)。
點擊 ifdef 或 endif 可快速選中條件編譯部分;點擊左側的折疊圖標,可折疊條件編譯部分代碼。
注意
- Android 和 iOS 平台不支持通過條件編譯來區分,如果需要區分 Android、iOS 平台,請通過調用 uni.getSystemInfo 來獲取平台信息。支持
ifios
、ifAndroid
代碼塊,可方便編寫判斷。 - 有些跨端工具可以提供js的條件編譯或多態,但這對於實際開發遠遠不夠。uni-app不止是處理js,任何代碼都可以多端條件編譯,才能真正解決實際項目的跨端問題。另外所謂多態在實際開發中會造成大量冗余代碼,很不利於復用和維護。舉例,微信小程序主題色是綠色,而百度支付寶小程序是藍色,你的應用想分平台適配顏色,只有條件編譯是代碼量最低、最容易維護的。
- 有些公司的產品運營總是給不同平台提不同需求,但這不是拒絕uni-app的理由。關鍵在於項目里,復用的代碼多還是個性的代碼多,正常都是復用的代碼多,所以仍然應該多端。而個性的代碼放到不同平台的目錄下,差異化維護。
使用示例
<template>
<view>
<!-- #ifdef H5 -->
<view>我希望只在h5頁面中看見</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>我希望只在微信小程序頁面中看見</view>
<!-- #endif -->
</view>
</template>
<script>
export default {
onLoad() {
// #ifdef H5
console.log('我希望h5中打印')
// #endif
// #ifdef MP-WEIXIN
console.log('我希望微信小程序中打印')
// #endif
}
}
</script>
<style>
/* h5中的樣式 */
/* #ifdef H5 */
view {
color: hotpink;
}
/* #endif */
/* 微信小程序中的樣式 */
/* #ifdef MP-WEIXIN */
view {
color: #0000FF;
}
/* #endif */
</style>
效果