
简体中文
App.uvue
是uni-app-x的主组件。
所有页面都是在App.uvue
下进行切换的,是应用入口文件。但App.uvue
本身不是页面,这里不能编写视图元素,也就是没有<template>
。
这个文件的作用包括:
应用生命周期仅可在App.uvue
中监听,在页面监听无效。
App.uvue
仅支持选项式,暂不支持组合式写法。
uni-app-x
支持如下应用生命周期函数:
生命周期回调,监听应用初始化,应用初始化完成时触发,全局只触发一次。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9 | 4.0 | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | OnLaunchOptions | 是 | - | - | - | ||||||||||||||||||||||||
|
生命周期回调 监听应用显示
应用启动,或从后台进入前台显示时触发
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9 | 4.0 | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | OnShowOptions | 是 | - | - | - | ||||||||||||||||||||||||
|
在微信小程序下,关闭弹出的原生窗体也会触发应用的onShow。比如关闭chooseImage、chooseVideo、chooseMedia、previewImage、chooseLocation、openLocation、scanCode等弹出的窗体。
生命周期回调 监听应用隐藏
应用从前台进入后台时触发
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9 | 4.0 | - |
在微信小程序下,打开全屏原生窗体也会触发应用的onHide。比如chooseImage、chooseVideo、chooseMedia、previewImage、chooseLocation、openLocation、scanCode。可以简单理解为弹出的这些原生窗体盖住了js写的小程序。
监听应用退出。app-uvue-android 3.9+
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
x | x | 3.9 | x | - |
错误监听函数 应用发生脚本错误或 API 调用报错时触发 4.33+ App 端支持监听异步逻辑中的错误
WARNING
onError
可以监听以下来源中的同步错误:
无法监听异步逻辑(例如:setTimeout
)中的错误和应用初始化之前、 App 崩溃等错误。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 4.21 | 4.21 | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
error | any | 是 | - | - | 错误信息 |
最后一个页面按下Android back键,常用于自定义退出。app-uvue-android 3.9+
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
x | x | 3.9 | x | - |
页面不存在监听函数
应用要打开的页面不存在时触发,会带上页面信息回调该函数
注意:
onPageNotFound
监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面。onPageNotFound
回调中又重定向到另一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,并且不再回调 onPageNotFound
。Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | x | x | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | OnPageNotFoundOption | 是 | - | - | - | ||||||||||||||||||||||||
|
未处理的 Promise 拒绝事件监听函数
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | x | x | - |
监听系统主题变化
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
x | 4.41 | x | x | - |
监听主题变化一般不推荐这个生命周期。而是使用uni api方式。详见:uni-app x主题适配
示例代码
<script lang="uts">
import { state, setLifeCycleNum, setAppLaunchPath, setAppShowPath } from './store/index.uts'
let firstBackTime = 0
export default {
// #ifndef APP-ANDROID
mixins: [
{
data() {
return {
appMixinDataMsg: 'App.uvue mixin data msg'
}
}
}],
// #endif
onLaunch: function (options) {
console.log(options)
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1000)
setAppLaunchPath(options.path)
console.log('App Launch')
// #ifdef UNI-APP-X && APP-ANDROID
const performance = uni.getPerformance()
const observer : PerformanceObserver = performance.createObserver((entryList : PerformanceObserverEntryList) => {
console.log('observer:entryList.getEntries()')
console.log(entryList.getEntries())
})
observer.observe({
entryTypes: ['render', 'navigation'],
} as PerformanceObserverOptions)
// #endif
},
onShow: function (options) {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum + 100)
setAppShowPath(options.path)
if(this.globalPropertiesStr === 'default string'){
setLifeCycleNum(state.lifeCycleNum + 10)
}
console.log('App Show')
},
onHide: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide')
},
// #ifdef APP-ANDROID
onLastPageBackPress: function () {
// 自动化测试
setLifeCycleNum(state.lifeCycleNum - 1000)
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
uni.showToast({
title: '再按一次退出应用',
position: 'bottom',
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
}
},
onExit() {
console.log('App Exit')
},
// #endif
onError: function(err: any) {
console.log('App Error', err)
setLifeCycleNum(state.lifeCycleNum + 100)
},
methods: {
checkLaunchPath() : boolean {
const HOME_PATH = 'pages/index/index'
if (state.appLaunchPath != HOME_PATH) {
return false
}
if (state.appShowPath != HOME_PATH) {
return false
}
return true
},
// #ifndef APP-ANDROID
checkAppMixin() : boolean {
if(this.globalMixinDataMsg1 != '通过 defineMixin 定义全局 mixin data') {
return false
}
if(this.appMixinDataMsg != 'App.uvue mixin data msg') {
return false
}
return true
}
// #endif
}
}
</script>
<style>
@import './styles/common.css';
.list-item-text {
line-height: 36px;
}
.split-title {
margin: 20px 0 5px;
padding: 5px 0;
border-bottom: 1px solid #dfdfdf;
}
.btn-view {
margin: 10px 0;
padding: 10px;
border: 1px solid #dfdfdf;
border-radius: 3px;
}
</style>
<style>
.text-red{
color: red;
}
</style>
注意
App.uvue
中监听,在其它页面监听无效。uni.getLaunchOptionsSync
获取,详见uni.exit()
是热退出,此时很多代码逻辑仍然在运行,有些on的事件监听并没有off,需要开发者在onExit生命周期中编写代码处理。比如在app的onLaunch里通过onXX监听了某事件,那么就需要在onExit里调用offXX取消某事件的监听,否则反复热退出、启动,会多次on而不会off,这会引发内存泄露。HBuilderX 3.99+
小程序有 globalData,这是一种简单的全局变量机制。这套机制在 uni-app-x 里也可以使用,仅 iOS uts 插件
环境不支持。
以下是 App.uvue 中定义globalData的相关配置:
<script lang="uts">
export default {
globalData: {
str: 'global data str',
num: 123,
bool: true
}
}
</script>
页面或组件中通过 getApp().globalData
访问。
<script lang="uts">
export default {
methods: {
getGlobalData() {
const app = getApp()
this.globalDataStr = app.globalData.str
this.globalDataNum = app.globalData.num
this.globalDataBool = app.globalData.bool
}
}
}
</script>
注意: uni-app x
中 globalData
的数据结构与类型通过 App.uvue
中的 globalData
初始值定义,后续只能读取或修改,不能新增或删除。
globalData是简单的全局变量,其他状态管理方式,可参考文档全局变量和状态管理。
在 App.uvue methods
中,可以定义全局方法,这里定义的方法,在项目中可以通过 getApp().vm?.methodName()
调用, 例如:
### 示例
> [hello uni-app x](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/alpha//pages/API/get-app/get-app.uvue)
::: preview https://hellouniappx.dcloud.net.cn/web/#/pages/API/get-app/get-app
> appRedirect https://hellouniappx.dcloud.net.cn/appredirect.html?path=pages/API/get-app/get-app
>Template
```vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1; padding-bottom: 20px">
<!-- #endif -->
<view>
<page-head title="getApp"></page-head>
<view class="uni-padding-wrap">
<button @click="getGlobalData">get globalData</button>
<template v-if="originGlobalData.str.length">
<text class="uni-common-mt bold">初始的 globalData:</text>
<text class="uni-common-mt">globalData string: {{ originGlobalData.str }}</text>
<text class="uni-common-mt">globalData number: {{ originGlobalData.num }}</text>
<text class="uni-common-mt">globalData boolean: {{ originGlobalData.bool }}</text>
<text class="uni-common-mt">globalData object: {{ originGlobalData.obj }}</text>
<text class="uni-common-mt">globalData null: {{ originGlobalData.null }}</text>
<text class="uni-common-mt">globalData array: {{ originGlobalData.arr }}</text>
<text class="uni-common-mt">globalData Set: {{ originGlobalData.mySet }}</text>
<text class="uni-common-mt">globalData Map: {{ originGlobalData.myMap }}</text>
<text class="uni-common-mt">globalData func 返回值: {{ originGlobalDataFuncRes }}</text>
</template>
<button @click="setGlobalData" class="uni-common-mt">
set globalData
</button>
<template v-if="newGlobalData.bool">
<text class="uni-common-mt bold">更新后的 globalData:</text>
<text class="uni-common-mt">globalData string: {{ newGlobalData.str }}</text>
<text class="uni-common-mt">globalData number: {{ newGlobalData.num }}</text>
<text class="uni-common-mt">globalData boolean: {{ newGlobalData.bool }}</text>
<text class="uni-common-mt">globalData object: {{ newGlobalData.obj }}</text>
<text class="uni-common-mt">globalData null: {{ newGlobalData.null }}</text>
<text class="uni-common-mt">globalData array: {{ newGlobalData.arr }}</text>
<text class="uni-common-mt">globalData Set: {{ newGlobalData.mySet }}</text>
<text class="uni-common-mt">globalData Map: {{ newGlobalData.myMap }}</text>
<text class="uni-common-mt">globalData func 返回值: {{ newGlobalDataFuncRes }}</text>
</template>
<text class="uni-common-mt">点击按钮调用 App.uvue methods</text>
<text class="uni-common-mt">increasetLifeCycleNum 方法</text>
<button class="uni-common-mt" @click="_increasetLifeCycleNum">
increase lifeCycleNum
</button>
<text class="uni-common-mt">lifeCycleNum: {{ lifeCycleNum }}</text>
<!-- #ifndef MP -->
<button class="uni-common-mt" @click="getAndroidApplication">
getAndroidApplication
</button>
<text class="uni-common-mt">androidApplication is null: {{ androidApplication == null }}</text>
<!-- #endif -->
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<style>
.bold {
font-weight: bold;
}
.hr {
border-bottom: 1px solid #ccc;
}
</style>
Script
import { state, setLifeCycleNum } from '@/store/index.uts'
type MyGlobalData = {
str : string,
num : number,
bool : boolean,
obj : UTSJSONObject,
null : string | null,
arr : number[],
mySet : string[],
myMap : UTSJSONObject,
func : () => string
}
export default {
data() {
return {
originGlobalData: {
str: '',
num: 0,
bool: false,
obj: {
str: '',
num: 0,
bool: false
} as UTSJSONObject,
null: null,
arr: [] as number[],
mySet: [] as string[],
myMap: {},
func: () : string => ''
} as MyGlobalData,
originGlobalDataFuncRes: '',
newGlobalData: {
str: '',
num: 0,
bool: false,
obj: {
str: '',
num: 0,
bool: false
} as UTSJSONObject,
null: null,
arr: [] as number[],
mySet: [] as string[],
myMap: {},
func: () : string => ''
} as MyGlobalData,
newGlobalDataFuncRes: '',
lifeCycleNum: 0,
androidApplication: null as any | null
}
},
onReady() {
this.lifeCycleNum = state.lifeCycleNum
},
methods: {
getGlobalData() {
const app = getApp()
this.originGlobalData.str = app.globalData.str
this.originGlobalData.num = app.globalData.num
this.originGlobalData.bool = app.globalData.bool
this.originGlobalData.obj = app.globalData.obj
this.originGlobalData.null = app.globalData.null
this.originGlobalData.arr = app.globalData.arr
app.globalData.mySet.forEach((value : string) => {
this.originGlobalData.mySet.push(value)
})
app.globalData.myMap.forEach((value : any, key : string) => {
this.originGlobalData.myMap[key] = value
})
this.originGlobalData.func = app.globalData.func
this.originGlobalDataFuncRes = this.originGlobalData.func()
},
setGlobalData() {
const app = getApp()
app.globalData.str = 'new globalData str'
app.globalData.num = 100
app.globalData.bool = true
app.globalData.obj = {
str: 'new globalData obj str',
num: 200,
bool: true
}
app.globalData.null = 'not null'
app.globalData.arr = [1, 2, 3]
app.globalData.mySet = new Set(['a', 'b', 'c'])
app.globalData.myMap = new Map([
['a', 1],
['b', 2],
['c', 3]
])
app.globalData.func = () : string => {
return 'new globalData func'
}
this.newGlobalData.str = app.globalData.str
this.newGlobalData.num = app.globalData.num
this.newGlobalData.bool = app.globalData.bool
this.newGlobalData.obj = app.globalData.obj
this.newGlobalData.null = app.globalData.null
this.newGlobalData.arr = app.globalData.arr
app.globalData.mySet.forEach((value : string) => {
this.newGlobalData.mySet.push(value)
})
app.globalData.myMap.forEach((value : any, key : string) => {
this.newGlobalData.myMap[key] = value
})
this.newGlobalData.func = app.globalData.func
this.newGlobalDataFuncRes = this.newGlobalData.func()
},
_increasetLifeCycleNum: function () {
const app = getApp()
app.vm!.increasetLifeCycleNum()
this.lifeCycleNum = state.lifeCycleNum
},
// 自动化测试
setLifeCycleNum(num : number) {
setLifeCycleNum(num)
},
// #ifndef MP
getAndroidApplication() : boolean {
const app = getApp()
this.androidApplication = app.getAndroidApplication()
return this.androidApplication !== null
}
// #endif
},
}
:::
注意
HBuilderX 4.31 getApp()
返回值调整为 UniApp
类型,调用 App.uvue
中定义的全局方法,需要由 getApp().methodName()
调整为 getApp().vm?.methodName()
。
在App.uvue
中,可以定义一些全局通用样式,这里定义的class,每个页面都可以直接使用。