UniApp生命周期:应用的生老病死
什么是生命周期?应用的命运轨迹
生命周期是指应用从创建、运行到销毁的整个过程中,在特定时刻自动执行的函数。理解UniApp的生命周期,就像掌握了应用的"命运密码",能够在恰当的时机执行恰当的操作。
┌───────────────────────────────────────────────────────┐
│ 生命周期的关键价值 │
├─────────────────────────┬─────────────────────────────┤
│ 正确的时机 │ 在恰当的时刻执行代码 │
├─────────────────────────┼─────────────────────────────┤
│ 资源管理 │ 合理分配和释放系统资源 │
├─────────────────────────┼─────────────────────────────┤
│ 用户体验 │ 控制加载状态和过渡效果 │
├─────────────────────────┼─────────────────────────────┤
│ 数据流控制 │ 管理数据的获取与更新时机 │
└─────────────────────────┴─────────────────────────────┘
UniApp的三层生命周期:宇宙、星球与生命
UniApp拥有三层生命周期系统,从大到小分别是:应用生命周期(App)、页面生命周期(Page)和组件生命周期(Component)。这就像宇宙、星球和生命的关系,大的包含小的,各自又有独立的运行规律。
应用生命周期(App):王国的兴衰史
应用生命周期管理整个应用的启动、运行和关闭过程,是最外层的生命周期。
┌──────────────────────────────────────────────────────────────────┐
│ 应用生命周期流程 │
└─────────────────────────┬────────────────────────────────────────┘
│
┌───────────▼───────────┐
│ onLaunch │◄─── 应用初次启动
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ onShow │◄─── 应用启动或从后台进入前台
└───────────┬───────────┘
│
│
┌─────────────┴─────────────┐
│ │
┌───────────▼───────────┐ ┌───────────▼───────────┐
│ 运行中的应用 │ │ onHide │◄─── 应用从前台进入后台
└───────────┬───────────┘ └───────────┬───────────┘
│ │
└───────────┬───────────────┘
│
┌─────────▼─────────┐
│ onUnload │◄─── 应用关闭
└───────────────────┘
生活类比:王国的一生
🏰 把应用比作一个王国:
- onLaunch: 王国建立,国王登基仪式。这只会发生一次,是各种制度、法规的初始化时刻。
- onShow: 王国开始日常运转,城门打开,商贩进城,百姓开始活动。每次王国从休眠中苏醒都会发生。
- onHide: 夜幕降临,城门关闭,王国进入休眠状态。人们仍在王国中,但活动减少。
- onUnload: 王国灭亡或被征服,所有资源被回收或重组。
代码示例:应用生命周期
// App.vue
export default {
// 应用第一次启动执行,全局只触发一次
onLaunch: function(options) {
console.log('应用初始化啦!');
console.log('启动参数:', options);
// 初始化工作 - 检查更新
this.checkUpdate();
// 初始化全局配置
this.globalData.theme = uni.getStorageSync('theme') || 'light';
},
// 应用显示出来时触发(从后台到前台)
onShow: function(options) {
console.log('应用进入前台啦!');
console.log('场景值:', options.scene);
// 恢复应用状态
this.resumeMusic();
// 检查登录状态
if(this.checkSessionTimeout()) {
uni.navigateTo({
url: '/pages/login/login' });
}
},
// 应用隐藏时触发(从前台到后台)
onHide: function() {
console.log('应用进入后台啦!');
// 保存应用状态
this.saveGameProgress();
this.pauseMusic();
// 记录退出时间
this.globalData.lastExitTime = Date.now();
},
// 应用错误触发
onError: function(err) {
console.error('应用遇到错误:', err);
this.reportErrorToServer(err);
},
// 全局数据和方法
globalData: {
userInfo: null,
theme: 'light',
lastExitTime: 0
},
methods: {
checkUpdate() {
// 检查更新逻辑
},
reportErrorToServer(error) {
// 错误上报逻辑
},
resumeMusic() {
// 恢复背景音乐
},
pauseMusic() {
// 暂停背景音乐
},
saveGameProgress() {
// 保存游戏进度
},
checkSessionTimeout() {
// 检查登录会话是否超时
}
}
}
页面生命周期(Page):城市的日常运转
页面生命周期管理单个页面的加载、显示、隐藏和卸载过程,是应用中的第二层生命周期。
┌──────────────────────────────────────────────────────────────────┐
│ 页面生命周期流程 │
└─────────────────────────┬────────────────────────────────────────┘
│
┌───────────▼───────────┐
│ onLoad │◄─── 页面加载,只触发一次
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ onShow │◄─── 页面显示
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ onReady │◄─── 页面初次渲染完成
└───────────┬───────────┘
│
┌─────────────┴─────────────┐
│ │
┌───────────▼───────────┐ ┌───────────▼───────────┐
│ 页面保持显示 │ │ onHide │◄─── 页面隐藏
└───────────┬───────────┘ └───────────┬───────────┘
│ │
│ │
│ ┌─────────────▼─────────────┐
│ │ onUnload │◄─── 页面卸载
│ └─────────────┬─────────────┘
│ │
└────────────┬──────────────┘
│
┌─────────▼─────────┐
│ onPullDownRefresh │◄─── 下拉刷新
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ onReachBottom │◄─── 上拉加载
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ onShareAppMessage│◄─── 用户点击分享
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ onPageScroll │◄─── 页面滚动
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ onResize │◄─── 页面尺寸变化
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ onTabItemTap │◄─── 点击Tab时
└───────────────────┘
生活类比:城市的一天
🏙️ 把页面比作一座城市:
- onLoad: 城市建设完成,道路、建筑和基础设施就位。居民开始搬入(参数传递)。
- onShow: 城市开始运作,商店开门,交通运行。每次这座城市被关注时都会发生。
- onReady: 城市所有服务全部启动完毕,居民可以正常使用所有设施。
- onHide: 临时封城,暂停大部分活动,但基础设施保留。
- onUnload: 城市被废弃或重建,所有资源回收。
- onPullDownRefresh: 城市大扫除,更新和刷新各种设施。
- onReachBottom: 城市向郊区扩张,增加新的区域和设施。
- onPageScroll: 居民在城市中移动,从一个区域到另一个区域。
- onShareAppMessage: 向其他城市发送使者,介绍本城市的特色。
代码示例:页面生命周期
// pages/home/index.vue
export default {
data() {
return {
banners: [],
products: [],
loading: true,
pageNum: 1
}
},
// 页面加载时,只触发一次
onLoad: function(options) {
console.log('页面加载啦,参数是:', options);
// 解析页面参数
if (options.category) {
this.currentCategory = options.category;
}
// 初始化页面数据
this.initData();
},
// 页面显示时触发
onShow: function() {
console.log('页面显示啦');
// 更新购物车角标
this.updateCartBadge();
// 检查登录状态
this.checkLoginStatus();
},
// 页面初次渲染完成
onReady: function() {
console.log('页面渲染完成啦');
// 获取组件实例
this.bannerSwiper = this.selectComponent('.banner-swiper');
// 初始化图表
setTimeout(() => {
this.initChart();
}, 300);
},
// 页面隐藏时
onHide: function() {
console.log('页面隐藏啦');
// 暂停页面动画或视频
this.pauseAllMedia();
},
// 页面卸载时
onUnload: function() {
console.log('页面卸载啦');
// 清理资源,取消请求
if (this.loadDataTimer) {
clearTimeout(this.loadDataTimer);
}
// 销毁图表实例
if (this.chart) {
this.chart.dispose();
}
},
// 下拉刷新触发
onPullDownRefresh: function() {
console.log('下拉刷新啦');
// 重新加载第一页数据
this.pageNum = 1;
this.products = [];
this.loadProducts().then(() => {
// 停止下拉刷新动画
uni.stopPullDownRefresh();
});
},
// 上拉加载更多
onReachBottom: function() {
console.log('触底加载更多啦');
if (!this.isLastPage) {
this.pageNum++;
this.loadProducts();
}
},
// 用户分享时触发
onShareAppMessage: function(options) {
console.log('用户点击分享', options);
return {
title: '发现了一个好用的商城',
path: '/pages/home/index',
imageUrl: '/static/share-img.png'
}
},
// 页面滚动触发
onPageScroll: function(e) {
// 控制顶部导航栏样式变化
if (e.scrollTop > 100) {
this.showTopBar = true;
} else {
this.showTopBar = false;
}
},
// Tab点击事件(tabBar页面)
onTabItemTap: function(item) {
console.log('点击了Tab', item.index);
// 重置页面状态
if (item.index === 0) {
this.resetHomePageState();
}