UniApp App.vue 文件完整教程

一、App.vue 核心概念与作用

​App.vue​ ​ 是 UniApp 应用的​​主组件​ ​和​​入口文件​ ​,所有页面都在其内部进行切换。它本身不是页面,因此不能编写 <template> 模板内容。App.vue 承担着三大核心职责:

  1. ​应用生命周期管理​ - 监听应用的启动、显示、隐藏等全局事件
  2. ​全局样式定义​ - 定义影响所有页面的基础样式
  3. ​全局数据存储​ - 提供跨页面共享的数据存储机制

​重要特性​​:

  • 应用生命周期​仅可在 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 应用的核心配置文件,掌握其正确的使用方法对于开发高质量的多端应用至关重要。关键要点包括:

  1. ​生命周期管理​ :正确使用 onLaunchonShowonHide 等应用生命周期函数
  2. ​全局数据​ :合理使用 globalData 存储跨页面共享的数据
  3. ​全局样式​:在 App.vue 中定义全局样式,避免重复代码
  4. ​启动参数​ :通过 onLaunch 参数或 uni.getLaunchOptionsSync() 获取启动信息
  5. ​错误处理​ :使用 onErroronUnhandledRejection 进行全局错误捕获

遵循这些最佳实践,可以构建出性能优良、体验一致的跨平台应用。

相关推荐
.ZGR.2 小时前
Java小项目——文件管理系统 V3.0
java·开发语言
qiyue772 小时前
AI浪潮下,前端的路在何方,附前端转KMP实践
前端·ai编程
Moment2 小时前
历史性突破!LCP 和 INP 终于覆盖所有主流浏览器,iOS 性能盲点彻底消失
前端·javascript·面试
小小荧2 小时前
Hono与Honox一次尝试
前端·后端
superman超哥2 小时前
Rust Trait 定义与实现:类型系统的多态基石
开发语言·rust·类型系统·rust trait·定义与实现·多态基石
superman超哥2 小时前
Rust 方法与关联函数:所有权语义下的行为设计
开发语言·rust·rust底层探索·rust方法与关联函数·所有权语义下的行为设计
糕......2 小时前
Java IO流:数据传输的艺术与机制
java·开发语言·网络·学习
菩提小狗2 小时前
第2天:基础入门-Web应用&架构搭建&漏洞&HTTP数据包&代理服务器|小迪安全笔记|网络安全|
前端·安全·架构
ctrigger2 小时前
监理工程师考试题型有哪些?4科题型+分值表
大数据·javascript·算法