uni-app 條件編譯
跨端相容
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 |
H5 | H5 |
MP-WEIXIN | 微信小程式 |
MP-ALIPAY | 支付寶小程式 |
MP-BAIDU | 百度小程式 |
MP-TOUTIAO | 位元組跳動小程式 |
MP-QQ | QQ小程式 |
MP | 微信小程式/支付寶小程式/百度小程式/位元組跳動小程式/QQ小程式 |
支援的檔案
- .vue
- .js
- .css
- pages.json
- 各預編譯語言檔案,如:.scss、.less、.stylus、.ts、.pug
注意: 條件編譯是利用註釋實現的,在不同語法裡註釋寫法不一樣,js使用 // 註釋、css 使用 /* 註釋 */、vue/nvue 模板裡使用 <!-- 註釋 -->;
API 的條件編譯
// #ifdef %PLATFORM% 平臺特有的API實現 // #endif
示例,如下程式碼僅在 App 下出現:
//#ifdef APP_PLUS plus.push.addEventListener('click',function(msg){ var payload = null; var action = ''; if(msg.payload){ if(typeof msg.payload === 'string'){ payload = JSON.parse(msg.payload); } action = payload.action; if(action === 'open'){ plus.webview.open(payload.url) } } }) //#endif
示例,如下程式碼不會在 H5 平臺上出現:
//#ifndef H5 uni.scanCode({ success:(res)=>{ console.log(res.result); } }); //#endif
除了支援單個平臺的條件編譯外,還支援多平臺同時編譯,使用 || 來分隔平臺名稱。
示例,如下程式碼會在 App 和 H5 平臺上出現:
//#ifdef APP-PLUS || H5 uni.chooseVideo({ success:(res)=>{ console.log(res.result); } }); //#endif
元件的條件編譯
<!-- #ifdef %PLATFORM% --> 平臺特有的元件 <!-- #endif -->
示例,如下廣告元件僅會在微信小程式中出現:
<!-- #ifdef MP-WEIXIN --> <ad unit-id="test"></ad> <!-- #endif -->
樣式的條件編譯
/* #ifdef %PLATFORM% */ 平臺特有樣式 /* #endif */
注意: 樣式的條件編譯,無論是 css 還是 sass/scss/less/stylus 等預編譯語言中,必須使用 /*註釋*/ 的寫法。
正確寫法
/* #ifdef MP-WEIXIN */ .wx-color{ color:#fff000; } /* #endif */
錯誤寫法
// #ifdef MP-WEIXIN .wx-color{ color:#fff000 } // #endif
pages.json 的條件編譯
下面的頁面,只有執行至 App 時才會編譯進去。
// #ifdef APP-PLUS { "path":"pages/api/speech/speech", "style":{ "navigationBarTitleText":"語音識別" } } //#endif
不同平臺下的特有功能,以及小程式平臺的分包,都可以透過 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等子目錄,存放不同平臺的檔案。
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的理由。關鍵在於專案裡,複用的程式碼多還是個性的程式碼多,正常都是複用的程式碼多,所以仍然應該多端。而個性的程式碼放到不同平臺的目錄下,差異化維護。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70018483/viewspace-2900875/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Rust 條件編譯Rust編譯
- doxygen 宏定義/宏編譯/條件編譯/預處理/預編譯 不處理、忽略條件、分析所有條件、滿足所有條件的方法編譯
- Rust 交叉編譯與條件編譯總結Rust編譯
- C語言 - 條件編譯C語言編譯
- PLSQL Language Reference-PL/SQL語言基礎-條件編譯-條件編譯指令限制SQL編譯
- PLSQL Language Reference-PL/SQL語言基礎-條件編譯-條件編譯舉例SQL編譯
- .NET探索平臺條件編譯編譯
- Java條件編譯是什麼?Java編譯
- 「譯」編寫更好的 JavaScript 條件式和匹配條件的技巧JavaScript
- 【C進階】22、條件編譯分析編譯
- go怎麼沒有條件編譯Go編譯
- 條件編譯符號與公佈編譯符號
- oracle 10g的條件編譯Oracle 10g編譯
- Rust 在 cargo 中進行條件編譯RustCargo編譯
- 前端學習(2366):條件編譯跨端相容前端編譯跨端
- 【譯】編寫更好JavaScript條件語句的5個技巧JavaScript
- C語言的條件編譯#if, #elif, #else, #endif、#ifdef, #ifndefC語言編譯
- 條件編譯、多檔案程式設計、結構體編譯程式設計結構體
- c++進階(一)C語言條件編譯及編譯預處理階段C++C語言編譯
- uni-app 通過命令列編譯打包APP命令列編譯
- uni-app轉小程式遇到的問題 (元件使用插槽的問題)(跨端相容、條件編譯)(小程式自定義膠囊按鈕封裝)(uni-app掛載原型鏈)APP元件跨端編譯封裝原型
- Rust 跨平臺與條件編譯總結 2019.1.3Rust編譯
- PLSQL Language Reference-PL/SQL語言基礎-條件編譯-獲取和列印編譯後的原始碼文字SQL編譯原始碼
- 【譯】React的8種條件渲染方法React
- 「譯」寫好JavaScript條件語句的5條守則JavaScript
- C語言學習第18篇---巨集定義與使用 / 條件編譯使用分析C語言編譯
- 在命令列中使用 msbuild 定義多個編譯條件 DefineConstants 時出錯命令列UI編譯
- Python 工匠:編寫條件分支程式碼的技巧Python
- 條件編輯及宏定義學習小結
- 條件反射反射
- 條件渲染
- 【譯】JavaScript 中寫好條件語句的五個技巧JavaScript
- 【譯】javascript中寫好條件語句的五個技巧JavaScript
- Guru of the Week 條款24:編譯級防火牆 (轉)編譯防火牆
- SQL中on條件與where條件的區別[轉]SQL
- PL/SQL 條件SQL
- react 條件渲染React
- 條件和排序排序