# App.uvue

App.uvue是uni-app-x的主组件。

所有页面都是在App.uvue下进行切换的,是应用入口文件。但App.uvue本身不是页面,这里不能编写视图元素,也就是没有<template>

这个文件的作用包括:

  1. 监听应用生命周期
  2. 配置全局变量globalData
  3. 编写全局可用的method方法
  4. 配置全局样式

应用生命周期仅可在App.uvue中监听,在页面监听无效。

App.uvue仅支持选项式,暂不支持组合式写法。

# 应用生命周期

uni-app-x 支持如下应用生命周期函数:

# onLaunch?(options: OnLaunchOptions): void;

生命周期回调,监听应用初始化,应用初始化完成时触发,全局只触发一次。

# onLaunch 兼容性

Web Android iOS
4.0 3.9 4.0

# 参数

名称 类型 必填 默认值 兼容性 描述
options OnLaunchOptions - - -
名称 类型 必备 默认值 兼容性 描述
path string - - 应用启动页面路径
appScheme string -
首次启动时的Scheme。返回值与App.onLaunch的回调参数一致
appLink string -
首次启动时的appLink。返回值与App.onLaunch的回调参数一致
  • 如果应用通过scheme或applink(通用链接)启动,可在本生命周期获取相应参数。配置scheme或applink需在AndroidManifest.xml或info.plist中配置,打包后生效。

# 参见

# onShow?(options: OnShowOptions): void;

生命周期回调 监听应用显示

应用启动,或从后台进入前台显示时触发

# onShow 兼容性

Web Android iOS
4.0 3.9 4.0

# 参数

名称 类型 必填 默认值 兼容性 描述
options OnShowOptions - - -
名称 类型 必备 默认值 兼容性 描述
path string - - 应用启动页面路径
appScheme string -
本次启动时的Scheme。返回值与App.onShow的回调参数一致
appLink string -
本次启动时的appLink。返回值与App.onShow的回调参数一致
  • 如果应用通过scheme或applink(通用链接)启动(不管首次启动还是后台激活到前台,均触发本生命周期),可在本生命周期获取。配置scheme或applink需在AndroidManifest.xml或info.plist中配置,打包后生效。
  • 如开发App页面直达功能,在配置scheme或通用链接并打包后,一般在onShow生命周期里解析scheme或applink参数,然后自行写navigatorTo等路由API跳转页面。onShow的好处是不管首页启动还是后台激活到前台,都触发。当然如果是初次启动,仍然会先打开App的首页再执行开发者编写的路由代码。
  • Web的页面直达无需使用scheme或通用链接,所有页面地址都可以直接在地址栏访问。

# 参见

# onHide?(): void;

生命周期回调 监听应用隐藏

应用从前台进入后台时触发

# onHide 兼容性

Web Android iOS
4.0 3.9 4.0

# 参见

# onLastPageBackPress?(): void;

最后一个页面按下Android back键,常用于自定义退出。app-uvue-android 3.9+

# onLastPageBackPress 兼容性

Web Android iOS
x 3.9 x

# 参见

# onExit?(): void;

监听应用退出。app-uvue-android 3.9+

# onExit 兼容性

Web Android iOS
x 3.9 x

# onError?(error: any): void;

错误监听函数 应用发生脚本错误或 API 调用报错时触发 4.33+ App 端支持监听异步逻辑中的错误

WARNING

onError 可以监听以下来源中的同步错误:

  • 组件渲染器
  • 事件处理器
  • 生命周期钩子
  • setup() 函数
  • 侦听器

无法监听异步逻辑(例如:setTimeout)中的错误和应用初始化之前、 App 崩溃等错误。

# onError 兼容性

Web Android iOS
4.0 4.21 4.21

# 参数

名称 类型 必填 默认值 兼容性 描述
error any - - 错误信息

# 参见

示例代码

<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 + 111)
      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(error: any) {
      console.log('App Error', error)
      setLifeCycleNum(state.lifeCycleNum + 122)
    },
    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中监听,在其它页面监听无效
  • 应用启动参数,也可以在API uni.getLaunchOptionsSync获取,详见
  • 由于Android的uni.exit()热退出,此时很多代码逻辑仍然在运行,有些on的事件监听并没有off,需要开发者在onExit生命周期中编写代码处理。比如在app的onLaunch里通过onXX监听了某事件,那么就需要在onExit里调用offXX取消某事件的监听,否则反复热退出、启动,会多次on而不会off,这会引发内存泄露。

# globalData

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 xglobalData 的数据结构与类型通过 App.uvue 中的 globalData 初始值定义,后续只能读取或修改,不能新增或删除。

globalData是简单的全局变量,其他状态管理方式,可参考文档全局变量和状态管理

# 全局方法

App.uvue methods 中,可以定义全局方法,这里定义的方法,在项目中可以通过 getApp().vm?.methodName() 调用, 例如:

<!-- App.uvue -->
<script lang="uts">
  export default {
    onLaunch: function () {
      console.log('App Launch')
    },
    onShow: function () {
      console.log('App Show')
    },
    onHide: function () {
      console.log('App Hide')
    },
    methods: {
      globalFn(){
        console.log('The global fn is triggered')
      }
    }
  }
</script>

<!-- pages/index/index.uvue -->
<template>
  <view>
    <button @click="triggerGlobalFn">trigger global fn</button>
  </view>
</template>

<script lang="uts">
  export default {
    onReady() {
      getApp().globalFn()
    },
    methods: {
      triggerGlobalFn() {
        const app = getApp()
        app.vm?.globalFn()
      }
    }
  }
</script>

注意

HBuilderX 4.31 getApp() 返回值调整为 UniApp 类型,调用 App.uvue 中定义的全局方法,需要由 getApp().methodName() 调整为 getApp().vm?.methodName()

# 全局样式

App.uvue中,可以定义一些全局通用样式,这里定义的class,每个页面都可以直接使用。