學(xué)習(xí)導(dǎo)覽
uniapp調(diào)研資料
1.認識vue
2.搭建vue應(yīng)用
3.組件與api
4.生命周期
5.條件編譯
6.原生APP中集成uni小程序
7.小程序打開集成原生App插件
8.原生插件開發(fā)
9.熱更新
10.優(yōu)缺點
demo運行指南
首先安裝HBuilderX和微信開發(fā)者程序
開發(fā)工具下載
https://www.dcloud.io/hbuilderx.html
微信開發(fā)者工具下載(小程序預(yù)覽需要)
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
然后導(dǎo)入項目并運行
項目git地址:https://github.com/willShuhuan/DSH_Uni.git
<h2 id="chapacter1">1.認識vue</h2>
Vue (讀音 /vju?/,類似于 view) 是一套用于構(gòu)建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設(shè)計為可以自底向上逐層應(yīng)用。Vue 的核心庫只關(guān)注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。另一方面,當(dāng)與現(xiàn)代化的工具鏈以及各種支持類庫結(jié)合使用時,Vue 也完全能夠為復(fù)雜的單頁應(yīng)用提供驅(qū)動。
uniapp是什么
uni-app 是一個使用 Vue.js 開發(fā)所有前端應(yīng)用的框架,開發(fā)者編寫一套代碼,可發(fā)布到iOS、Android、H5、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘/淘寶)、快應(yīng)用等多個平臺。
多端運行的原因->目標(biāo)平臺安裝文件打包
uniapp能力
| 能力 | Y/N | 說明 |
|---|---|---|
| 跨端能力 | ? | 安卓、ios、微信小程序、其他小程序 |
| 原生App喚起uni小程序能力 | ? | 需要集成uni小程序SDK并導(dǎo)入小程序wgt包 |
| 原生App跳轉(zhuǎn)小程序二級頁面 | ? | 可以傳遞json、字符串等 |
| uni小程序喚起原生App能力 | ? | 需要開發(fā)對應(yīng)的Android/iOS插件,或通過插件市場下載,支持json、字符串等通用數(shù)據(jù)類型的傳遞 |
| 第三方服務(wù) | ? | 支付/推送/三方登錄/分享/地圖等 |
| HBuilderX熱編譯 | ? | 支持手機、微信、瀏覽器實時預(yù)覽 |
| fragment/viewController嵌套小程序頁面 | ? | 啟動小程序相當(dāng)于打開一個新的Activity,詳見頁面最下說明 |
| uniapp頁面加載原生fragment/viewController | ? | uni小程序在App端實際上是運行在一個WebActivity之上,可以拿到ActivityContext進而獲取FragmentManager處理Fragment的展示隱藏,雖然這種方式可行,但是在uniapp上切換選項卡的時候要不斷處理fragment的內(nèi)部邏輯,相當(dāng)于fragment生命周期的監(jiān)控任務(wù)交給uniapp來執(zhí)行而不是fragment本身 |
Vue.js優(yōu)點
- 體積小
壓縮后33K; - 更高的運行效率
基于虛擬dom,一種可以預(yù)先通過JavaScript進行各種計算,把最終的DOM操作計算出來并優(yōu)化的技術(shù),由于這個DOM操作屬于預(yù)處理操作,并沒有真實的操作DOM,所以叫做虛擬DOM。 - 雙向數(shù)據(jù)綁定
讓開發(fā)者不用再去操作dom對象,把更多的精力投入到業(yè)務(wù)邏輯上; - 生態(tài)豐富、學(xué)習(xí)成本低
市場上擁有大量成熟、穩(wěn)定的基于vue.js的ui框架、常用組件!拿來即用實現(xiàn)快速開發(fā)!
對初學(xué)者友好、入門容易、學(xué)習(xí)資料多;
<h2 id="chapacter2">2.搭建vue應(yīng)用</h2>
2.1 html內(nèi)嵌式
使用cdn或者本地文件的形式引入vue(不建議使用,知道就好)
<html>
<head>
<meta charset="utf-8">
<title>vue實例</title>
<!-- 直接引入方式 -->
<!-- <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> -->
<!-- <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script> -->
<!-- cdn方式 -->
<!-- 開發(fā)環(huán)境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生產(chǎn)環(huán)境版本,優(yōu)化了尺寸和速度 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue"></script> -->
</head>
<body>
</body>
<html>
2.2 vue cli 終端命令行安裝(需要掌握)
https://uniapp.dcloud.io/quickstart?id=_2-通過vue-cli命令行
- 安裝npm
npm全稱為Node Package Manager, 是一個基于Node . js的包管理器,也是整個Node . js社區(qū)最流行、支持的第三方模塊最多的包管理器。
npm -v 查看npm - 安裝cnpm
npm install -g cnpm -registry=https://registry.npm. taobao.org - 安裝vue一cli
cnpm install -g @vue/cli - 安裝webpack
cnpm install -g webpack
webpack是JavaScript 打包器(module bundler) - vue ui —> 瀏覽器可視化頁面 —> 搭建vue 應(yīng)用 -> 使用HBuilder X打開
2.3 HBuilder X 搭建uniapp(建議使用)
https://uniapp.dcloud.io/quickstart?id=_1-通過-hbuilderx-可視化界面
創(chuàng)建
- HBuilderX->文件->新建項目->選擇模板
image
運行
https://uniapp.dcloud.io/quickstart?id=運行uni-app



發(fā)布
<h2 id="chapacter3">3.組件與api</h2>
https://uniapp.dcloud.io/component/README
https://uniapp.dcloud.io/api/README
3.1 組件的使用
uni-app為開發(fā)者提供了一系列基礎(chǔ)組件,類似HTML里的基礎(chǔ)標(biāo)簽元素。
但uni-app的組件與HTML不同,而是與小程序相同,更適合手機端使用。
- 視圖容器:view scroll-view等
- 基礎(chǔ)內(nèi)容:text icon等
- 表單組件:button form radio checkbox等
- 媒體組件:video 等
- 其他:地圖,導(dǎo)航,畫布,擴展組件等
<template>
<view class="content">
<scroll-view show-scrollbar="false">
<navigator style="width: 100%; margin-top: 10rpx;" url="./tab_main_task" hover-class="navigator-hover" open-type="switchTab">
<button type="primary">navigator跳轉(zhuǎn)到新頁面</button>
</navigator>
<video style="width: 100%; margin-top: 10rpx;" src="http://gusteau-test.oss-cn-hangzhou.aliyuncs.com/material/transcode/video/2020/07/24/HK2mmdYW_1595570205480.mp4"></video>
<form @submit="formSubmit" @reset="formReset" class="form">
<view class="title">{{switchvalue}}</view>
<switch @change="switchChange" color="#FF6723" name="switch"></switch>
<view class="title">radio單選框</view>
<radio-group name="radio">
<label>
<radio value="radio1" /><text>選項一</text>
</label>
<label>
<radio value="radio2" /><text>選項二</text>
</label>
</radio-group>
<view class="title">checkbox復(fù)選框</view>
<checkbox-group name="checkbox">
<label>
<checkbox value="checkbox1" /><text>選項一</text>
</label>
<label>
<checkbox value="checkbox2" /><text>選項二</text>
</label>
</checkbox-group>
<view class="title">slider</view>
<slider value="50" name="slider" show-value></slider>
<view class="title">input輸入框</view>
<input class="uni-input" name="input" placeholder="這是一個輸入框" />
<button form-type="submit" type="primary" class="button">Submit</button>
<button type="warn" form-type="reset" class="button">Reset</button>
</form>
</scroll-view>
</view>
</template>
3.2 API調(diào)用
uni-app的js API由標(biāo)準ECMAScript的js API 和 uni 擴展 API 這兩部分組成。
以上述代碼為例,處理表單提交時,可以使用uni.showModal彈出一個提示框
formSubmit: function(e) {
console.log('form發(fā)生了submit事件,攜帶數(shù)據(jù)為:' + JSON.stringify(e.detail.value))
var formdata = e.detail.value
uni.showModal({
content: '表單數(shù)據(jù)內(nèi)容:' + JSON.stringify(formdata),
showCancel: false
});
}
如果想模擬一個網(wǎng)絡(luò)請求,可以這樣
uni.request({
url: 'https://www.example.com/request', //僅為示例,并非真實接口地址。
data: {
text: 'uni.request'
},
header: {
'custom-header': 'hello' //自定義請求頭信息
},
success: (res) => {
console.log(res.data);
this.text = 'request success';
}
});
3.3 自定義組件
封裝可復(fù)用的組件,可以在其他的頁面使用它
- 首先編寫一個組件
<template>
<h3 @click='clickFun'>我是自定義組件:{{msg}}</h3>
</template>
<script>
export default {
name:'testComponent',
props:{
msg:{
type:String,
default:'default msg'
}
},
methods:{
clickFun:function(){
this.msg = '改變后的組件屬性',
this.$emit('clickFun',this.msg);
}
}
}
</script>
<style>
</style>
- 在其他的組件中導(dǎo)入、聲明、傳入必要的參數(shù)并使用它
<template>
<view>
<!-- 3.自定義組件使用 msg是自定義組件的一個屬性-->
<testComponent style="margin-top: 50px;" msg="默認屬性" @clickFun="sonComponentClickCallback"></testComponent>
<div>{{callback}}</div>
</view>
</template>
<script>
//1.導(dǎo)入
import testComponent from '../components/testcomponent.vue'
export default{
components:{
//2.聲明
testComponent
},
data() {
return {
callback: ''
}
},
methods:{
sonComponentClickCallback:function(e){
// this.callback = e;
console.log(e);
}
}
}
</script>
<style>
</style>
<h2 id="chapacter4">4.生命周期</h2>
https://uniapp.dcloud.io/collocation/frame/lifecycle
4.1 整個應(yīng)用的生命周期
只能在App.vue中監(jiān)聽,
- onLaunch 當(dāng)uni-app 初始化完成時觸發(fā)(全局只觸發(fā)一次)
- onShow 當(dāng) uni-app 啟動,或從后臺進入前臺顯示
- onHide 當(dāng) uni-app 從前臺進入后臺
- onError 當(dāng) uni-app 報錯時觸發(fā)
- onUniNViewMessage 對 nvue 頁面發(fā)送的數(shù)據(jù)進行監(jiān)聽
下面的代碼中,在App啟動時,為應(yīng)用底部tabBar設(shè)置了消息氣泡,在實際的開發(fā)中,也可以做一些資源和SDK的初始化工作,比如為安卓和iOS原生插件內(nèi)部的SDK做一些初始化工作
<script>
export default {
onLaunch: function() {
console.log('App Launch')
setTimeout(() => {
uni.setTabBarBadge({
index: 1,
text: '9'
});
uni.showTabBarRedDot({
index: 3
});
}, 1000);
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
}
</script>
4.2 每個頁面的生命周期
onLoad、onShow、onReady、onHide等
- onPageScroll 頁面在垂直方向已滾動的距離(單位px)
onPageScroll:function(e){
this.scrollTop = e.scrollTop;
}
- onBackPress 觸發(fā)返回行為的來源:'backbutton'——左上角導(dǎo)航欄按鈕及安卓返回鍵;'navigateBack'——uni.navigateBack() 方法。
- onTabItemTap 當(dāng)前點擊的tabItem
- 返回對象
{"index":4,"text":"我的","pagePath":"pages/main/tab_main_mine"}
image
- 返回對象
4.3 通過頁面生命周期控制原生插件的生命周期
在需要與原生插件進行交互時,下面的代碼可以通過監(jiān)聽頁面生命周期控制安卓原生插件fragment的顯示隱藏
onHide() {
console.log("onHide");
testModule.hideFragment();
},
onShow() {
console.log("onShow");
testModule.showFragment();
}
<h2 id="chapacter5">5.條件編譯</h2>
【官網(wǎng)介紹】 https://uniapp.dcloud.io/platform
5.1 簡介
語法: 以 #ifdef 或 #ifndef 加 %PLATFORM% 開頭,以 #endif 結(jié)尾。
- ifdef:if defined 僅在某平臺存在
- ifndef:if not defined 除了某平臺均存在
- %PLATFORM%:平臺名稱
#ifdef APP-PLUS
需條件編譯的代碼
#endif
#ifndef H5
需條件編譯的代碼
#endif
#ifdef H5 || MP-WEIXIN
需條件編譯的代碼
#endif
在vue中的使用,與注釋代碼的語法一致,mac下command+/或者control+alt+/提示
<template>
<!-- #ifdef %PLATFORM% -->
平臺特有的組件
<!-- #endif -->
</template>
<script>
// #ifdef APP-PLUS
平臺特有API實現(xiàn)
// #endif
</script>
<style>
/* #ifdef %PLATFORM% */
平臺特有樣式
/* #endif */
</style>
5.2 pages.json條件編譯
例:實現(xiàn)微信小程序和客戶端的差異化顯示
pages.json中使用條件編譯注釋微信平臺需要屏蔽的頁面
{
"pages":[
//#ifndef MP-WEIXIN
{
"path": "pages/main/tab_main_video",
"style": {}
},
{
"path" : "pages/main/tab_main_game",
"style" : {}
},
//#endif
...
],
"tabBar" : {
...
"list":[
//#ifndef MP-WEIXIN
{
"pagePath" : "pages/main/tab_main_video",
"iconPath" : "static/mipmap/tabbar/ic_nav_video_unselected.png",
"selectedIconPath" : "static/mipmap/tabbar/ic_nav_video_selected.png",
"text" : "刷視頻"
},
{
"pagePath" : "pages/main/tab_main_game",
"iconPath" : "static/mipmap/tabbar/ic_nav_game_unselected.png",
"selectedIconPath" : "static/mipmap/tabbar/ic_nav_game_selected.png",
"text" : "玩游戲"
},
// #endif
]
...
}
}
<p style="color:red">注意:pages中條件編譯的代碼要與tabbar中的條件編譯代碼要一致,否則運行時會報錯</p>
編譯之后在微信開發(fā)者工具下看到代碼不包含被我們條件編譯排除掉的代碼,可以說HBuilderX在編譯過程中幫我們?nèi)サ袅似脚_無關(guān)代碼
效果
其他平臺
微信平臺
5.3 API條件編譯
- 針對各個平臺的特性不同,處理一些交互,比如表單校驗提示,在原生APP可以以吐司形式,在H5平臺上可以處理為Alert彈出框
- 控制各個平臺業(yè)務(wù)代碼的差異
查看以下代碼
- v-show 屬性可以理解為css的display屬性,控制組件顯示隱藏
- 通過帶參函數(shù)show(param)返回值控制v-show的值
- gotoNativePage()是一個跳轉(zhuǎn)到原生App頁面的一個方法,需要原生插件的支持
- ifios和ifAndroid可以針對移動端平臺進行處理
<template>
<div>
<div class="content">
<button v-show="show('android')" class="button" type="primary" @click="gotoNativePage">Android跳轉(zhuǎn)原生Activity</button>
<button v-show="show('ios')" class="button" type="primary" @click="gotoNativePage">iOS跳轉(zhuǎn)原生ViewController</button>
</div>
</div>
</template>
<script>
const testModule = uni.requireNativePlugin("willA-SopModule");
export default {
data() {
return {
title: 'Hello',
show: function(plat){
// #ifdef H5
return true
// #endif
// #ifdef APP-PLUS
if(plat==='android'){
if (uni.getSystemInfoSync().platform == "android") {
return true
}else{
return false
}
}else{
if (uni.getSystemInfoSync().platform == "android") {
return false
}else{
return true
}
}
// #endif
}
}
}
};
</script>
<style>
.content {
text-align: center;
height: 100%;
margin-top: 150upx;
}
.button {
width: 60%;
margin-top: 100upx;
}
</style>
上述代碼運行結(jié)果就是:
- 在H5平臺下 安卓和 ios跳轉(zhuǎn)按鈕都展示
- 在安卓平臺下,只會展示跳轉(zhuǎn)安卓activity按鈕
- 在iOS平臺下,只會展示跳轉(zhuǎn)iOS viewController的按鈕
其他條件編譯的使用場景放在第7小節(jié)講解
<h2 id="chapacter6">6.原生APP中集成uni小程序</h2>
https://nativesupport.dcloud.net.cn/UniMPDocs/UseSdk/android
uni小程序SDK,是為原生App打造的可運行基于 uni-app 開發(fā)的小程序前端項目的框架,從而幫助原生App快速獲取小程序的能力,效果如下:

流程
- 原生工程中 添加基礎(chǔ)依賴庫及資源文件
uniMPSDK-release.aar //必須集成
uniapp-release.aar //必須集成
sqlite-release.aar
msa_mdid_1.0.13.aar //必須集成 注意(2.8.0版本的SDK及以下版本請集成miit_mdid_1.0.10.aar)
messaging-release.aar
iBeacon-release.aar
fingerprint-release.aar
contacts-release.aar
Bluetooth-release.aar
android-gif-drawable-release@1.2.17.aar //必須集成
gradle配置
//必須配置
def mfph = [
//宿主包名
"apk.applicationId" : "xxx.xxx.xxxxx",
]
android {
defaultConfig {
targetSdkVersion 26 //最高28最優(yōu)26 設(shè)置值域超過28可能在android10以上手機出現(xiàn)白屏問題。
ndk {
abiFilters 'x86','armeabi-v7a',"arm64-v8a" //不支持armeabi
}
manifestPlaceholders = mfph
}
//此處配置必須添加 否則無法正確運行
aaptOptions {
additionalParameters '--auto-add-overlay'
//noCompress 'foo', 'bar'
ignoreAssetsPattern "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
}
}
//導(dǎo)入aar需要的配置
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
//導(dǎo)入SDK相關(guān)依賴jar、aar
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.aar'], dir: 'libs')
//必須添加的依賴
implementation 'com.android.support:recyclerview-v7:27.1.0'
implementation 'com.android.support:support-v4:27.1.0'
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.alibaba:fastjson:1.1.46.android'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation 'com.facebook.fresco:animated-gif:1.13.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
}

-
生成小程序應(yīng)用資源, 在uniapp中制作wgt包
image 導(dǎo)入小程序應(yīng)用資源
打開android原生項目。在主Module模塊的assets路徑下創(chuàng)建apps/(內(nèi)置uni小程序的appid)/www 路徑。例如:apps/__UNI__04E3A11/www。將之前導(dǎo)出的應(yīng)用資源包解壓釋放到apps/__UNI__04E3A11/www路徑下。
小程序id在uniapp工程中可以看到
安卓工程配置

注意,以下配置項必須添加,并且按照要求填寫,否則不停報錯
在原生App中開啟小程序
//配置菜單
MenuActionSheetItem item = new MenuActionSheetItem("關(guān)于", "gy");
MenuActionSheetItem item1 = new MenuActionSheetItem("獲取當(dāng)前頁面url", "hqdqym");
List<MenuActionSheetItem> sheetItems = new ArrayList<>();
sheetItems.add(item);
sheetItems.add(item1);
DCSDKInitConfig config = new DCSDKInitConfig.Builder()
.setCapsule(true)
.setMenuDefFontSize("16px")
.setMenuDefFontColor("#ff00ff")
.setMenuDefFontWeight("normal")
.setMenuActionSheetItems(sheetItems)
.setEnableBackground(true)//開啟后臺運行
.build();
//開啟小程序
DCUniMPSDK.getInstance().startApp(mContext,"__UNI__1F21932","/pages/product/product?id=10");
<h2 id="chapacter7">7.小程序集成原生App插件</h2>
uniapp支持原生插件擴展,包括插件市場云端插件和本地插件兩種方式,這節(jié)講解云端插件,本地插件在第8節(jié)進行說明
-
首先在manifest中選擇云端插件
image -
在插件市場導(dǎo)入
image -
回到HBuilderX中導(dǎo)入插件
image -
自定義基座
image 打包完成之后,按照插件使用說明在需要的地方引入并使用它,效果如下
<script>
//在頁面中引入插件
const dcRichAlert = uni.requireNativePlugin('DCloud-RichAlert')
export default{
onTabItemTap:function(Object){
console.log(Object);
},
methods:{
showPlugin(){
//編寫調(diào)用代碼
dcRichAlert.doSomthing();
}
}
}
</script>
<h2 id="chapacter8">8.原生插件開發(fā)</h2>
當(dāng)HBuilderX中提供的能力無法滿足App功能需求,需要通過使用Andorid/iOS原生開發(fā)實現(xiàn)時,可使用App離線SDK開發(fā)原生插件來擴展原生能力。
https://nativesupport.dcloud.net.cn/NativePlugin/course/android
- 擴展 module(偏向功能模塊)
- 擴展組件 component(偏向UI組件)
擴展 module
https://nativesupport.dcloud.net.cn/NativePlugin/course/android?id=創(chuàng)建android-studio的module模塊
- 1.首先創(chuàng)建一個AS工程,工程內(nèi)創(chuàng)建Android Library,導(dǎo)入uniapp-relase.aar并依賴
- 2.編寫Module類,設(shè)計交互場景
public class TestModule extends WXModule {
private static final String TAG = "uniTestModule";
FragmentManager fragmentManager;
FragmentTransaction transaction;
Fragment fragment;
Context mContext;
FrameLayout frameLayout;
//run ui thread
@JSMethod(uiThread = true)
public void testAsyncFunc(JSONObject options, JSCallback callback) {
Log.e(TAG, "testAsyncFunc--"+options);
if(callback != null) {
JSONObject data = new JSONObject();
data.put("code", "success");
callback.invoke(data);
//callback.invokeAndKeepAlive(data);
}
}
//run JS thread
@JSMethod (uiThread = false)
public JSONObject testSyncFunc(){
JSONObject data = new JSONObject();
data.put("code", "success");
return data;
}
@JSMethod (uiThread = true)
public void gotoNativeMainPage(JSONObject jsonObject){
Log.d(TAG, "gotoNativeMainPage: "+jsonObject);
if(mWXSDKInstance != null) {
Intent intent = new Intent(mWXSDKInstance.getContext(), TestActivity.class);
intent.putExtra("data",jsonObject.toString());
mWXSDKInstance.getContext().startActivity(intent);
}
}
@JSMethod (uiThread = true)
public void showFragment(){
mContext = mWXSDKInstance.getContext();
Log.d(TAG, "showFragment: "+mContext);//PandoraEntryActivity
fragmentManager = ((Activity) mContext).getFragmentManager();
transaction = fragmentManager.beginTransaction();
fragment = new TestFragment();
frameLayout = new FrameLayout(mContext);
int height = Util.getScreenHeidth(mContext);
int bottomMargin = Util.dip2px(mContext,50);
FrameLayout.LayoutParams params1 =new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height-bottomMargin
);
((Activity) mContext).addContentView(frameLayout,params1);
frameLayout.setId(View.generateViewId());
transaction.replace(frameLayout.getId(), fragment);
transaction.commitAllowingStateLoss();
}
@JSMethod (uiThread = true)
public void hideFragment(){
transaction = fragmentManager.beginTransaction();
transaction.hide(fragment).commit();
fragment.onPause();
}
}
- 3 編寫通過Module進行交互的業(yè)務(wù)代碼
public class TestFragment extends Fragment {
private static final String TAG = "uniTestModule";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mine_layout, container,false);
return view;
}
}
public class TestActivity extends AppCompatActivity {
private static final String TAG = "uniTestModule";
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String data = getIntent().getStringExtra("data");
setContentView(R.layout.activity_test);
TextView textView = findViewById(R.id.text);
textView.setText(data);
}
}
- 4 通過gradle執(zhí)行打包構(gòu)建aar文件
-
5 配置package.json
image 6 將插件集成到項目中
項目根目錄下新建nativeplugins文件夾,將package.json放入此目錄,新建android文件夾放入安卓打包aar文件,新建ios文件夾配置放置ios打包.a文件-
7 manifest文件中配置本地模塊
image -
8 制作自定義基座(云打包)
image -
9 等待打包完成,在需要使用的地方調(diào)用插件即可
image -
10 在真機或模擬器上運行,點擊加載fragment按鈕,效果如下
image
<h2 id="chapacter9">9.熱更新</h2>
小程序平臺升級
uni-app發(fā)布為小程序的升級模式較簡單,只需將開發(fā)完的代碼提交小程序后臺,待審核通過后用戶將自動升級。
APP端的升級
- 整包更新,即常規(guī)的整個App安裝包重新下載安裝。(不是熱更新)
- 資源熱更新,即App不需要重新安裝,里面的js等前端代碼進行更新。(是熱更新)
App資源熱更新
https://ask.dcloud.net.cn/article/id-35667__page-4
適用小版本升級
通過生成移動APP資源升級包的方式進行差量(增量)升級,將uniapp發(fā)布為wgt升級包,通過服務(wù)端與前端配合的方式在移動端進行升級
- 以安卓為例,uniapp打包apk的過程就是把當(dāng)前uniapp工程包裝為一個安卓工程并進行壓縮打包的過程,uniapp中的代碼運行在一個Webview中(原生插件除外)
- 實際上,所以我們修改uniapp的代碼也只是修改了前端代碼,不管打包前還是打包為apk之后,也不可能中間會存在js2java或者js2OC這樣的代碼轉(zhuǎn)換過程(如果真有這種黑科技,就能真正的一統(tǒng)天下了)
- 所以,只需要把wgt升級包放在服務(wù)端,App端檢測到版本升級時,下載wgt資源并替換原來的資源就可以了,實際上,Tinker(http://www.itdecent.cn/p/076afb5cdd55) 等熱更新方案也是類似的原理
image
<h2 id="chapacter10">10.優(yōu)缺點</h2>
<strong style="color:red;font-size:20px">結(jié)論:優(yōu)點>缺點</strong>
雖然下面寫了更多的缺點,但總體來看,優(yōu)點遠大于缺點
優(yōu)點
- 跨平臺性,write once ,run everywhere,通過多平臺打包發(fā)布到對應(yīng)平臺,節(jié)約大量開發(fā)成本
- 對于前端開發(fā)人員比較友好,vue作為主流前端框架大多數(shù)人都掌握,只需要少量原生知識就能夠開發(fā)跨平臺的應(yīng)用
- 生態(tài)體系逐漸完善,很多大廠也在用,社區(qū)成長速度比較快
缺點
- 正是由于跨平臺特性,多端適配會占據(jù)相當(dāng)?shù)墓ぷ髁?,開發(fā)人員必須編寫很多條件編譯代碼,這會破壞代碼的整體結(jié)構(gòu)(畢竟在業(yè)務(wù)代碼中編寫很多平臺適配代碼看起來太不優(yōu)雅了),可讀性也會受到一定影響,而且坑多是必然的
- 對于Android和iOS開發(fā)人員來講,轉(zhuǎn)投uniapp學(xué)習(xí)成本很高(除了vue,還要學(xué)習(xí)html+js+css等知識),精通更是很難,這有點類似前兩年移動端轉(zhuǎn)投react native那樣,會而不精,代碼質(zhì)量無法得到充分保證(我也有朋友最近把公司的react native的項目完全重構(gòu)為原生代碼了)
- 前端人員依然無法解決所有問題,至少在目前的應(yīng)用場景中,很多需求仍然需要客戶端人員配合開發(fā)(對于前端人員而言,學(xué)習(xí)安卓iOS的成本也相當(dāng)可觀)
- 對于一些棘手的問題,參考的資料并不多,而且官方也很難第一時間回答你,甚至只能自己慢慢探索
- 陳舊的api:以安卓為例,uniapp云打包apk反編譯之后,發(fā)現(xiàn)入口程序PandoraEntry實際上是一個Activity而非API22(Android 5.1)后谷歌官方建議使用的v7包下的AppCompactActivity,這會影響ToolBar的使用
