一、App.vue 核心概念与作用
App.vue 是 UniApp 应用的主组件 和入口文件 ,所有页面都在其内部进行切换。它本身不是页面,因此不能编写 <template> 模板内容。App.vue 承担着三大核心职责:
- 应用生命周期管理 - 监听应用的启动、显示、隐藏等全局事件
- 全局样式定义 - 定义影响所有页面的基础样式
- 全局数据存储 - 提供跨页面共享的数据存储机制
重要特性:
- 应用生命周期仅可在 App.vue 中监听,在页面中监听无效
- 在 App.vue 的
onLaunch/onShow回调参数中可获取应用启动参数 - 对于 UniApp x 项目,使用 App.uvue 文件(js 引擎版使用 App.vue)
二、基本结构与最小示例
选项式 API(Vue2/3 通用)
<script>
export default {
// 应用初始化完成时触发(全局仅触发一次)
onLaunch(options) {
console.log('App Launch', options)
},
// 应用显示到前台时触发(从后台切换回)
onShow(options) {
console.log('App Show', options)
},
// 应用隐藏到后台时触发
onHide() {
console.log('App Hide')
},
// 应用报错时触发
onError(err) {
console.error('App Error', err)
}
}
</script>
<style>
/* 全局基础字体 */
page {
font-family: "PingFang SC";
}
/* 定义全局 CSS 变量 */
:root {
--theme-color: #007AFF;
}
</style>
组合式 API(Vue3)
<script setup>
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
// 应用初始化完成
onLaunch((options) => {
console.log('App Launch', options)
})
// 应用显示到前台
onShow((options) => {
console.log('App Show', options)
})
// 应用隐藏到后台
onHide(() => {
console.log('App Hide')
})
</script>
<style>
/* 全局样式 */
page {
background-color: #f8f8f8;
}
</style>
三、应用生命周期详解
核心生命周期函数
| 函数名 | 触发时机 | 典型应用场景 |
|---|---|---|
onLaunch |
应用初始化完成时触发(全局仅一次) | 全局配置、用户登录状态检查、版本更新检查 |
onShow |
应用启动或从后台进入前台时触发 | 数据刷新、重新建立网络连接、恢复用户状态 |
onHide |
应用从前台进入后台时触发 | 数据保存、断开网络连接、暂停非必要任务 |
onError |
应用报错时触发 | 错误上报、日志记录 |
onPageNotFound |
页面不存在时触发 | 页面重定向、错误处理 |
onThemeChange |
系统主题变化时触发 | 主题切换处理 |
onUnhandledRejection |
未处理的 Promise 拒绝事件时触发 | Promise 错误处理 |
生命周期执行顺序
应用启动时的执行顺序:
App.onLaunch → App.onShow → 页面beforeCreate → created → onLoad → onShow → mounted → onReady
页面跳转时的执行顺序(A页面跳转到B页面):
页面A.onHide → 页面B.beforeCreate → created → onLoad → onShow → mounted → onReady
页面返回时的执行顺序(B页面返回A页面):
页面B.onUnload → beforeDestroy → destroyed → 页面A.onShow
四、globalData 全局数据管理
定义全局数据
在 App.vue 中定义 globalData 对象:
<script>
export default {
globalData: {
// 用户信息
userInfo: null,
// 主题色
themeColor: '#007AFF',
// 接口地址
baseUrl: 'https://api.example.com',
// 版本号
version: '1.0.0'
},
onLaunch() {
// 初始化全局数据
this.globalData.userInfo = {
id: 1,
name: '张三',
token: 'xxx'
}
}
}
</script>
获取和修改全局数据
在页面或组件中操作全局数据:
// 获取全局数据
const app = getApp()
console.log(app.globalData.userInfo)
// 修改全局数据
app.globalData.userInfo.name = '李四'
// 在 App.vue 内部获取
onLaunch() {
// Vue2 非 V3 模式
console.log(this.$scope.globalData.userInfo)
// Vue3 模式
console.log(getApp({ allowDefault: true }).globalData.userInfo)
}
注意事项:
- 不能在模板中直接使用
getApp().globalData.xxx - 在 App.vue 的
onLaunch中,getApp()尚未生成,需要使用this.$scope.globalData(Vue2)或getApp({ allowDefault: true })(Vue3) - 全局数据会在应用运行期间一直存在,适合存储用户信息、配置信息等
五、全局样式配置
在 App.vue 中定义全局样式
<style>
/* 全局页面样式 */
page {
font-family: "PingFang SC", "Helvetica Neue", sans-serif;
font-size: 28rpx;
color: #333;
background-color: #f8f8f8;
}
/* 全局按钮样式 */
button {
border-radius: 8rpx;
}
/* 全局文本样式 */
.text-primary {
color: #007AFF;
}
.text-secondary {
color: #999;
}
/* 全局间距 */
.mt-20 {
margin-top: 20rpx;
}
.mb-20 {
margin-bottom: 20rpx;
}
/* 定义 CSS 变量 */
:root {
--primary-color: #007AFF;
--secondary-color: #666;
--border-radius: 8rpx;
}
</style>
在 pages.json 中配置全局样式
{
"globalStyle": {
"navigationBarBackgroundColor": "#007AFF",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "我的应用",
"backgroundColor": "#f8f8f8",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": true
}
}
样式优先级规则:
- 页面级样式 > 全局样式
- 组件内部样式 > 页面级样式
- 内联样式 > class 选择器
六、应用启动参数获取
在 App.vue 中获取启动参数
export default {
onLaunch(options) {
console.log('启动路径:', options.path)
console.log('启动场景:', options.scene)
console.log('查询参数:', options.query)
console.log('来源应用:', options.referrerInfo)
}
}
在页面中获取启动参数
export default {
onLoad() {
const options = uni.getLaunchOptionsSync()
console.log('启动参数:', options)
}
}
启动参数结构:
path: 启动路径scene: 启动场景值(小程序端)query: 查询参数对象referrerInfo: 来源应用信息
七、与页面组件的区别
| 对比项 | App.vue | 页面组件 |
|---|---|---|
| 模板 | 不能写 <template> |
必须有 <template> |
| 生命周期 | 应用级生命周期 | 页面级生命周期 |
| 作用域 | 全局作用域 | 页面作用域 |
| 数据存储 | globalData 全局数据 | data 局部数据 |
| 样式 | 全局样式 | 页面样式 |
| 路由 | 不参与路由 | 通过 pages.json 配置路由 |
八、常见问题与注意事项
1. 生命周期监听位置错误
错误示例:
// 在页面中监听应用生命周期(无效)
export default {
onLaunch() {
console.log('不会触发') // 不会执行
}
}
正确做法 :应用生命周期必须在 App.vue 中监听。
2. globalData 使用时机
错误示例:
onLaunch() {
// 此时 getApp() 尚未生成
console.log(getApp().globalData) // undefined
}
正确做法:
onLaunch() {
// Vue2 非 V3 模式
console.log(this.$scope.globalData)
// Vue3 模式
console.log(getApp({ allowDefault: true }).globalData)
}
3. 样式作用域问题
错误示例:
<style scoped>
/* 在 App.vue 中使用 scoped 会导致样式失效 */
page {
font-family: "PingFang SC";
}
</style>
正确做法 :App.vue 的 <style> 标签不能 使用 scoped 属性。
4. 模板内容错误
错误示例:
<template>
<!-- App.vue 不能写模板内容 -->
<view>这是错误写法</view>
</template>
正确做法 :App.vue 的 <template> 通常为空,或只放置全局组件(如加载提示、通知组件)。
5. 应用启动优化
优化建议:
- 避免在
onLaunch中执行大量同步操作 - 将耗时操作(如网络请求)放在异步任务中
- 使用
uni.preloadPage预加载常用页面 - 减少启动页的依赖资源
九、实战案例
案例1:用户登录状态管理
<script>
export default {
globalData: {
userInfo: null,
token: null
},
onLaunch() {
// 检查本地存储的用户信息
const userInfo = uni.getStorageSync('userInfo')
const token = uni.getStorageSync('token')
if (userInfo && token) {
this.globalData.userInfo = userInfo
this.globalData.token = token
// 验证 token 是否有效
this.checkToken()
} else {
// 跳转到登录页
uni.reLaunch({ url: '/pages/login/login' })
}
},
methods: {
checkToken() {
uni.request({
url: '/api/user/check',
header: {
'Authorization': 'Bearer ' + this.globalData.token
},
success: (res) => {
if (res.data.code !== 200) {
// token 失效,清除本地存储
uni.removeStorageSync('userInfo')
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/login' })
}
}
})
}
}
}
</script>
案例2:全局错误处理
<script>
export default {
onError(err) {
console.error('全局错误:', err)
// 错误上报
uni.request({
url: '/api/log/error',
method: 'POST',
data: {
error: err.message,
stack: err.stack,
timestamp: Date.now()
}
})
},
onUnhandledRejection(err) {
console.error('未处理的 Promise 拒绝:', err)
// Promise 错误上报
uni.request({
url: '/api/log/promise',
method: 'POST',
data: {
reason: err.reason,
timestamp: Date.now()
}
})
}
}
</script>
案例3:主题切换功能
<script>
export default {
globalData: {
theme: 'light'
},
onLaunch() {
// 读取本地存储的主题配置
const savedTheme = uni.getStorageSync('theme')
if (savedTheme) {
this.globalData.theme = savedTheme
this.setTheme(savedTheme)
}
},
methods: {
setTheme(theme) {
this.globalData.theme = theme
uni.setStorageSync('theme', theme)
// 设置主题色
if (theme === 'dark') {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#000000'
})
} else {
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#ffffff'
})
}
}
}
}
</script>
十、总结
App.vue 是 UniApp 应用的核心配置文件,掌握其正确的使用方法对于开发高质量的多端应用至关重要。关键要点包括:
- 生命周期管理 :正确使用
onLaunch、onShow、onHide等应用生命周期函数 - 全局数据 :合理使用
globalData存储跨页面共享的数据 - 全局样式:在 App.vue 中定义全局样式,避免重复代码
- 启动参数 :通过
onLaunch参数或uni.getLaunchOptionsSync()获取启动信息 - 错误处理 :使用
onError和onUnhandledRejection进行全局错误捕获
遵循这些最佳实践,可以构建出性能优良、体验一致的跨平台应用。