在 UniApp 开发中,生命周期钩子是贯穿应用、页面、组件执行全过程的核心机制,它决定了代码在什么时机执行、数据在什么阶段加载、资源在什么节点释放。掌握生命周期,是写出高性能、无 BUG 的 UniApp 应用的关键一步。
本文将系统梳理 UniApp 中应用生命周期、页面生命周期、组件生命周期三大核心模块,结合实战场景讲解用法,帮你彻底吃透生命周期逻辑。
一、什么是 UniApp 生命周期?
简单来说,UniApp 生命周期就是应用 / 页面 / 组件从创建、渲染、更新到销毁的整个过程,框架在这个过程中会暴露一系列固定名称的函数,我们可以在这些函数中编写业务逻辑,实现精准的时机控制。
UniApp 生命周期分为三大类,适用场景不同:
- 应用生命周期:全局生效,控制整个 App 的启动、显示、隐藏、错误等
- 页面生命周期:页面级别,控制单个页面的加载、显示、渲染、返回等
- 组件生命周期:组件级别,通用 Vue 生命周期,适用于所有组件
二、应用生命周期(全局)
应用生命周期定义在 App.vue 中,整个应用只会执行一次,用于处理全局初始化、全局状态管理、全局错误捕获等逻辑。
核心钩子函数
表格
| 钩子函数 | 触发时机 | 核心用途 |
|---|---|---|
onLaunch |
应用首次启动时触发(冷启动) | 初始化全局数据、获取设备信息、登录校验、请求全局配置 |
onShow |
应用启动、或从后台切换到前台时触发 | 恢复应用状态、刷新需要实时更新的数据 |
onHide |
应用从前台切换到后台时触发 | 暂停定时器、保存临时数据、停止播放音频 |
onError |
应用发生全局错误时触发 | 捕获全局异常、上报错误日志 |
onUniNViewMessage |
监听 nvue 页面发送的消息时触发 | nvue 与 vue 页面通信 |
实战代码示例(App.vue)
vue
<script>
export default {
// 1. 应用首次启动(只执行一次)
onLaunch() {
console.log('✅ 应用启动成功')
// 实战:获取用户设备信息
uni.getSystemInfo({
success: (res) => {
console.log('设备信息:', res)
}
})
// 实战:自动登录/校验token
this.checkLogin()
},
// 2. 应用切前台
onShow() {
console.log('✅ 应用进入前台')
// 实战:刷新页面数据、恢复定时器
},
// 3. 应用切后台
onHide() {
console.log('❌ 应用进入后台')
// 实战:清除定时器、暂停视频播放
},
// 4. 全局错误捕获
onError(err) {
console.error('❌ 应用报错:', err)
// 实战:上报错误到服务器
},
methods: {
checkLogin() {
// 登录逻辑
}
}
}
</script>
三、页面生命周期(页面级别)
页面生命周期定义在 pages.json 注册的页面中,每个页面独立拥有,用于处理页面加载、数据请求、页面显示隐藏等逻辑。
核心钩子函数
表格
| 钩子函数 | 触发时机 | 注意事项 | 核心用途 |
|---|---|---|---|
onLoad |
页面加载时触发(只执行一次) | 页面关闭后再次打开会重新触发 | 接收页面传参、发起网络请求、初始化页面数据 |
onShow |
页面显示时触发(每次切到当前页都会执行) | 从其他页面返回、应用切前台都会触发 | 刷新列表数据、更新页面状态 |
onReady |
页面初次渲染完成时触发(只执行一次) | 此时页面 DOM 渲染完毕 | 操作 DOM、获取节点信息、调用地图 / 画布组件 |
onHide |
页面隐藏时触发 | 跳转到其他页面、应用切后台都会触发 | 清除定时器、停止动画、释放资源 |
onUnload |
页面卸载时触发 | 点击返回按钮关闭页面时触发 | 销毁监听、清理缓存、防止内存泄漏 |
onPullDownRefresh |
下拉刷新时触发 | 需要在 pages.json 开启 enablePullDownRefresh | 下拉刷新数据 |
onReachBottom |
页面上拉触底时触发 | 用于分页加载 | 加载下一页数据 |
onShareAppMessage |
点击右上角分享时触发 | 微信小程序 / APP 生效 | 自定义分享内容 |
onPageScroll |
页面滚动时触发 | 高频触发,避免写复杂逻辑 | 监听滚动位置、吸顶效果 |
实战代码示例(页面.vue)
vue
<template>
<view class="page">
<view v-for="item in list" :key="item.id">{{ item.name }}</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [],
timer: null
}
},
// 1. 页面加载(接收参数+请求数据)
onLoad(options) {
console.log('页面加载,接收参数:', options)
// 发起网络请求
this.getList()
},
// 2. 页面显示(每次进入页面都执行)
onShow() {
console.log('页面显示')
},
// 3. 页面渲染完成(操作DOM)
onReady() {
console.log('页面渲染完成')
// 获取DOM节点信息
const query = uni.createSelectorQuery().in(this)
query.select('.page').boundingClientRect(res => {
console.log('页面高度:', res.height)
}).exec()
},
// 4. 页面隐藏
onHide() {
console.log('页面隐藏')
clearInterval(this.timer)
},
// 5. 页面卸载
onUnload() {
console.log('页面卸载')
// 彻底清理定时器,防止内存泄漏
clearInterval(this.timer)
},
// 下拉刷新
onPullDownRefresh() {
this.getList(() => {
// 数据加载完成停止刷新
uni.stopPullDownRefresh()
})
},
// 上拉加载更多
onReachBottom() {
console.log('触底加载下一页')
},
methods: {
getList(callback) {
// 模拟请求
setTimeout(() => {
this.list = [{ id: 1, name: '测试数据' }]
callback && callback()
}, 1000)
}
}
}
</script>
四、组件生命周期(Vue 标准)
UniApp 组件完全遵循 Vue 生命周期 ,同时兼容 Vue2 和 Vue3 写法,适用于自定义组件、页面中的组件。
Vue2 组件生命周期(最常用)
表格
| 钩子函数 | 触发时机 | 核心用途 |
|---|---|---|
beforeCreate |
实例创建前,数据观测未初始化 | 几乎不用 |
created |
实例创建完成,数据已绑定 | 请求数据、初始化变量(无 DOM) |
beforeMount |
挂载开始前,模板编译完成 | 准备渲染 |
mounted |
挂载完成,DOM 已渲染 | 操作 DOM、初始化第三方插件 |
beforeUpdate |
数据更新,DOM 未更新 | 数据更新前处理 |
updated |
数据更新,DOM 已更新 | 数据更新后操作 DOM |
beforeDestroy |
实例销毁前 | 清除定时器、解绑事件 |
destroyed |
实例销毁完成 | 资源释放 |
Vue3 组合式 API(setup 语法糖)
js
import { onMounted, onUnmounted, onUpdated } from 'vue'
onMounted(() => {
console.log('组件挂载完成')
})
onUnmounted(() => {
console.log('组件销毁')
})
五、生命周期执行顺序(核心重点)
这是面试和实战中最常考、最容易出错的知识点,必须牢记:
1. 应用启动顺序
onLaunch(应用) → onShow(应用) → onLoad(页面) → onShow(页面) → onReady(页面)
2. 页面跳转顺序
页面 A → 页面 B:A.onHide → B.onLoad → B.onShow → B.onReady
3. 页面返回顺序
页面 B → 页面 A:B.onUnload → A.onShow
4. 组件与页面生命周期关系
页面onLoad → 组件created → 组件mounted → 页面onShow → 页面onReady
六、生命周期实战避坑指南
-
网络请求放哪里?
- 只需要加载一次:放在
onLoad或created - 需要每次进入页面刷新:放在
onShow
- 只需要加载一次:放在
-
操作 DOM 必须用哪个?
- 页面:
onReady - 组件:
mounted✅ 此时 DOM 渲染完成,操作不会报错
- 页面:
-
定时器 / 监听一定要销毁
- 在
onUnload/beforeDestroy中清除,防止内存泄漏
- 在
-
onShow 慎用高频逻辑
- 页面切前台、返回都会触发,避免频繁请求接口
-
小程序与 App 生命周期兼容
- UniApp 生命周期是跨端的,大部分钩子在微信小程序、App、H5 中都能正常运行
七、总结
UniApp 生命周期是框架的核心执行流程,三大生命周期各司其职:
- 应用生命周期:掌控全局,处理应用级逻辑
- 页面生命周期:控制页面,处理页面加载、渲染、交互
- 组件生命周期:通用 Vue 标准,处理组件独立逻辑