# 全局 API

# 应用实例

# 兼容性

Web Android iOS
createApp() 4.0 4.11
createSSRApp() 4.0 4.11
app.mount() 4.0 4.11
app.unmount() 4.0 4.11
app.component() 4.0 4.11
app.directive() - - -
app.use() 4.0 3.99 4.11
app.mixin() 4.0 3.99 4.11
app.provide() 4.0 3.99 4.11
app.runWithContext() - - -
app.version 4.0 4.11
app.config - - -
app.config.errorHandler 4.0 x 4.11
app.config.warnHandler - - -
app.config.performance - - -
app.config.compilerOptions - - -
app.config.globalProperties 4.0 3.99 4.11
app.config.optionMergeStrategies - - -
globalData 4.0 3.9 4.0
onLaunch() 4.0 3.9 4.0
onShow() 4.0 3.9 4.0
onHide() 4.0 3.9 4.0
onLastPageBackPress() x 3.9 x
onExit() x 3.9 x
onError() 4.0 4.21 4.21

# app.component

如果同时传递一个组件名字符串及其定义,则注册一个全局组件;如果只传递一个名字,则会返回用该名字注册的组件 (如果存在的话)。

示例 详情

注册全局组件

使用全局组件

import App from './App.uvue'
import CompForAppComponent from '@/components/CompForAppComponent.uvue'
export function createApp() {
  const app = createSSRApp(App)
  app.component('CompForAppComponent', CompForAppComponent)
}

# app.use

app.use 支持通过对象字面量、函数及 definePlugin 方式定义插件。

支持传递插件参数,当传递插件参数时,app 的类型需要指定为 VueApp

示例 详情

选项式 API

组合式 API

<template>
  <view class="page">
    <CompForAppUse class="component-for-app-use" />
  </view>
</template>

<script lang="uts">
import CompForAppUse from '@/components/CompForAppUse.uvue'

export default {
  components: {
    CompForAppUse
  }
}
</script>

# app.config.globalProperties

请注意,globalProperties 是一个保留关键字,因此在项目中请勿声明名为 globalProperties 的变量。

在向 globalProperties 注册方法时,请使用直接函数表达式方式进行赋值。不支持先声明函数,再将其注册到 globalProperties 上的方式。同时,注册的函数一旦被赋值,不允许进行修改。

globalProperties 在编译时处理,因此确保你的操作在编译时是可知的。例如,将变量赋值给 globalProperties 时,这个变量在编译时必须是已知的,而不能是在运行时才能确定的变量。 当传递插件参数时,app 的类型需要指定为 VueApp

示例 详情

设置 app.config.globalProperties

选项式 API

组合式 API

<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex: 1; padding-bottom: 20px">
    <!-- #endif -->
    <view class="uni-padding-wrap">
      <text class="mt-10"
        >globalProperties string: {{ globalPropertiesStr }}</text
      >
      <text class="mt-10"
        >globalProperties number: {{ globalPropertiesNum }}</text
      >
      <text class="mt-10"
        >globalProperties boolean: {{ globalPropertiesBool }}</text
      >
      <text class="mt-10"
        >globalProperties object: {{ globalPropertiesObj }}</text
      >
      <text class="mt-10"
        >globalProperties null: {{ globalPropertiesNull }}</text
      >
      <text class="mt-10"
        >globalProperties array: {{ globalPropertiesArr }}</text
      >
      <text class="mt-10"
        >globalProperties set: {{ globalPropertiesSet }}</text
      >
      <text class="mt-10"
        >globalProperties map: {{ globalPropertiesMap }}</text
      >
      <text class="mt-10"
        >globalProperties reactiveObj.str:
        {{ globalPropertiesReactiveObj['str'] }}</text
      >
      <text class="mt-10"
        >globalProperties reactiveObj.num:
        {{ globalPropertiesReactiveObj['num'] }}</text
      >
      <text class="mt-10"
        >globalProperties reactiveObj.boolean:
        {{ globalPropertiesReactiveObj['bool'] }}</text
      >
      <text class="mt-10"
        >globalProperties fun 返回值: {{ globalPropertiesFn() }}</text
      >
      <button @click="updateGlobalProperties" class="mt-10">
        update globalProperties
      </button>
    </view>
    <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>

<script lang="uts">
type MyGlobalProperties = {
	str : string;
	num : number;
	bool : boolean;
	obj : UTSJSONObject;
	null : string | null;
	arr : number[];
	set : string[];
	map : UTSJSONObject;
	reactiveObj : UTSJSONObject;
	globalPropertiesFnRes: string
}
export default {
	data() {
		return {
			myGlobalProperties: {
				str: '',
				num: 0,
				bool: false,
				obj: {},
				null: null,
				arr: [],
				set: [],
				map: {},
				reactiveObj: {
					str: '',
					num: 0,
					bool: false,
				} as UTSJSONObject,
				globalPropertiesFnRes: '',
			} as MyGlobalProperties,
		}
	},
	onLoad() {
		this.getGlobalProperties()
	},
	onUnload(){
		this.resetGlobalProperties()
	},
	methods: {
		getGlobalProperties() {
			this.myGlobalProperties.str = this.globalPropertiesStr
			this.myGlobalProperties.num = this.globalPropertiesNum
			this.myGlobalProperties.bool = this.globalPropertiesBool
			this.myGlobalProperties.obj = this.globalPropertiesObj
			this.myGlobalProperties.null = this.globalPropertiesNull
			this.myGlobalProperties.arr = this.globalPropertiesArr
			this.myGlobalProperties.set = []
			this.globalPropertiesSet.forEach(item => {
				this.myGlobalProperties.set.push(item)
			})
			this.myGlobalProperties.map = {}
			this.globalPropertiesMap.forEach((value: number, key: string) => {
				this.myGlobalProperties.map[key] = value
			})
			this.myGlobalProperties.reactiveObj = this.globalPropertiesReactiveObj
			this.myGlobalProperties.globalPropertiesFnRes = this.globalPropertiesFn()
		},
		resetGlobalProperties() {
			this.globalPropertiesStr = 'default string'
			this.globalPropertiesNum = 0
			this.globalPropertiesBool = false
			this.globalPropertiesObj = {
				str: 'default globalProperties obj string',
				num: 0,
				bool: false,
			}
			this.globalPropertiesNull = null
			this.globalPropertiesArr = []
			this.globalPropertiesSet = new Set()
			this.globalPropertiesMap = new Map()
			this.globalPropertiesReactiveObj['str'] = 'default reactive string'
			this.globalPropertiesReactiveObj['num'] = 0
			this.globalPropertiesReactiveObj['bool'] = false
		},
		updateGlobalProperties() {
			this.globalPropertiesStr = 'new string'
			this.globalPropertiesNum = 100
			this.globalPropertiesBool = true
			this.globalPropertiesObj = {
				str: 'new globalProperties obj string',
				num: 100,
				bool: true,
			}
			this.globalPropertiesNull = 'not null'
			this.globalPropertiesArr = [1, 2, 3]
			this.globalPropertiesSet = new Set(['a', 'b', 'c'])
			this.globalPropertiesMap = new Map([['a', 1], ['b', 2], ['c', 3]])
			this.globalPropertiesReactiveObj['str'] = 'new reactive string'
			this.globalPropertiesReactiveObj['num'] = 200
			this.globalPropertiesReactiveObj['bool'] = true
			this.getGlobalProperties()
		}
	},
}
</script>

<style>
.uni-padding-wrap {
  padding: 10px;
}
</style>

# 应用生命周期

uni-app x 新增了 onLastPageBackPressonExit 应用级生命周期,Android退出应用逻辑写在app.uvue里,新建项目的模板自动包含相关代码。如需修改退出逻辑,请直接修改相关代码。

示例 详情

<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>

# 通用

Web Android iOS
version 4.0 4.11
nextTick() 4.0 4.11
defineComponent() 4.0 x x
defineAsyncComponent() - - -
defineCustomElement() - - -

# nextTick 使用注意事项

目前 nextTick 可以保证当前数据已经同步到 DOM,但是由于排版和渲染是异步的的,所以 nextTick 不能保证 DOM 排版以及渲染完毕。如果需要获取排版后的节点信息推荐使用 uni.createSelectorQuery 不推荐直接使用 Element 对象。在修改 DOM 后,立刻使用 Element 对象的同步接口获取 DOM 状态可能获取到的是排版之前的,而 uni.createSelectorQuery 可以保障获取到的节点信息是排版之后的。