生命周期
UniApp 的生命周期分为三个层次:应用生命周期、页面生命周期 和 组件生命周期。
- 应用生命周期:在App.vue中定义,包括onLaunch、onShow、onHide等。
- 页面生命周期:在页面vue文件中定义,包括onLoad、onShow、onReady、onHide、onUnload等。
- 组件生命周期:与Vue组件的生命周期相同,包括beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed等。
一、应用生命周期(App.vue)
-
onLaunch:当uni-app初始化完成时触发(全局只触发一次) -
onShow:当uni-app启动,或从后台进入前台显示时触发 -
onHide:当uni-app从前台进入后台时触发 -
onError:当uni-app报错时触发 -
onUniNViewMessage:对nvue页面发送的数据进行监听 -
onUnhandledRejection:对未处理的 Promise 拒绝事件监听函数 -
onPageNotFound:页面不存在监听函数 -
onThemeChange:监听系统主题变化// App.vue 示例 export default { onLaunch(options) { console.log('App Launch', options) // 获取启动参数 // #ifdef MP-WEIXIN console.log('微信小程序启动参数:', options.query) // #endif }, onShow(options) { console.log('App Show', options) }, onHide() { console.log('App Hide') }, onError(err) { console.error('App Error', err) } }
1、onLaunch(options) - 应用初始化
options 参数在不同平台的差异:
| 平台 | 参数说明 |
|---|---|
| 小程序 | query: 启动参数, scene: 场景值 |
| APP | provider: 推送厂商, path: 启动路径 |
| H5 | query: URL 参数 |
2、 onShow(options) - 应用显示
onShow(options) {
console.log('App Show')
// 检查登录状态
this.checkLoginStatus()
// 获取当前页面栈
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
console.log('当前页面:', currentPage)
// 检查版本更新(App)
// #ifdef APP-PLUS
this.checkAppUpdate()
// #endif
},
3、onError(error) - 错误监听
onError(error) {
console.error('App 错误:', error)
// 错误上报
this.reportError(error)
// 生产环境友好提示
// #ifndef DEBUG
uni.showToast({
title: '应用出错了,请重启',
icon: 'none',
duration: 3000
})
// #endif
// 记录错误日志
const errorLog = {
time: new Date().toISOString(),
error: error.toString(),
stack: error.stack,
platform: uni.getSystemInfoSync().platform
}
// 存储到本地
try {
const logs = uni.getStorageSync('error_logs') || []
logs.unshift(errorLog)
if (logs.length > 50) logs.pop() // 最多保存50条
uni.setStorageSync('error_logs', logs)
} catch (e) {
console.log('保存错误日志失败:', e)
}
},
4、onPageNotFound(res) - 页面不存在
onPageNotFound(res) {
console.log('页面不存在:', res)
// 重定向到404页面
uni.redirectTo({
url: '/pages/common/404'
})
// 或者重定向到首页
// uni.switchTab({
// url: '/pages/index/index'
// })
// 记录404日志
this.report404({
path: res.path,
query: res.query,
isEntryPage: res.isEntryPage,
time: new Date().toISOString()
})
},
5、onThemeChange(res) - 主题变化
onThemeChange(res) {
console.log('主题变化:', res)
// 更新主题
const theme = res.theme // 'light' 或 'dark'
this.globalData.theme = theme
// 发送全局事件
uni.$emit('themeChange', theme)
// 更新导航栏样式(App)
// #ifdef APP-PLUS
if (theme === 'dark') {
plus.navigator.setStatusBarStyle('light')
} else {
plus.navigator.setStatusBarStyle('dark')
}
// #endif
// 保存主题偏好
uni.setStorageSync('app_theme', theme)
},
二、页面生命周期(页面vue文件)
onInit:仅仅百度小程序监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoadonLoad:监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参),只触发一次onShow:监听页面显示,每次打开页面都会调用(包括从其他页面返回)onReady:监听页面初次渲染完成,只触发一次onHide:监听页面隐藏,当页面被隐藏时触发(比如跳转到其他页面)onUnload:监听页面卸载,当页面被关闭时触发(比如使用redirectTo或navigateBack跳转)onPullDownRefresh:监听用户下拉动作,用于下拉刷新onReachBottom:页面上拉触底事件的处理函数onShareAppMessage:用户点击右上角分享时触发onPageScroll:监听页面滚动,参数为ObjectonNavigationBarButtonTap:监听原生标题栏按钮点击事件onBackPress:监听页面返回,返回 event = {from: backbutton, navigateBack} ,backbutton 表示来源是左上角返回按钮或android返回键;navigateBack表示来源是uni.navigateBackonTabItemTap:点击 tab 时触发,参数为Object
| 生命周期 | Vue2 写法 | Vue3 `` 写法 | 说明 | 平台差异 |
|---|---|---|---|---|
| onInit | onInit() | const onInit = () => {} 需导出:export default { onInit } | 页面初始化 | 仅百度小程序支持,在 onLoad 之前执行 |
| onLoad | onLoad(options) | const onLoad = (options) => {} 需导出:export default { onLoad } | 页面加载,接收参数 | 全平台支持,页面加载时触发 |
| onShow | onShow() | const onShow = () => {} 需导出:export default { onShow } | 页面显示/切入前台 | 全平台支持,每次页面显示都触发 |
| onReady | onReady() | const onReady = () => {} 需导出:export default { onReady } | 页面初次渲染完成 | 全平台支持,可操作 DOM |
| onHide | onHide() | const onHide = () => {} 需导出:export default { onHide } | 页面隐藏/切入后台 | 全平台支持 |
| onUnload | onUnload() | const onUnload = () => {} 需导出:export default { onUnload } | 页面卸载 | 全平台支持 |
| onPullDownRefresh | onPullDownRefresh() | const onPullDownRefresh = () => {} 需导出:export default { onPullDownRefresh } | 监听用户下拉刷新 | 全平台支持,需在 pages.json 中配置 enablePullDownRefresh |
| onReachBottom | onReachBottom() | const onReachBottom = () => {} 需导出:export default { onReachBottom } | 页面上拉触底事件 | 全平台支持,需在 pages.json 中配置 onReachBottomDistance |
| onPageScroll | onPageScroll(e) | const onPageScroll = (e) => {} 需导出:export default { onPageScroll } | 监听页面滚动 | H5、小程序、App 支持,参数:{scrollTop} |
| onShareAppMessage | onShareAppMessage(options) | const onShareAppMessage = (options) => {} 需导出:export default { onShareAppMessage } | 用户点击右上角分享 | 仅小程序平台支持(微信、支付宝、百度、QQ、字节、快手),需返回分享配置对象 |
| onShareTimeline | onShareTimeline() | const onShareTimeline = () => {} 需导出:export default { onShareTimeline } | 分享到朋友圈 | 仅微信小程序 2.11.3+ 支持 |
| onAddToFavorites | onAddToFavorites(options) | const onAddToFavorites = (options) => {} 需导出:export default { onAddToFavorites } | 添加到收藏/我的小程序 | 仅微信小程序支持 |
| onBackPress | onBackPress(options) | const onBackPress = (options) => {} 需导出:export default { onBackPress } | 页面返回时触发 | H5 和 App 支持,options.from: 'backbutton' 或 'navigateBack' |
| onNavigationBarButtonTap | onNavigationBarButtonTap(e) | const onNavigationBarButtonTap = (e) => {} 需导出:export default { onNavigationBarButtonTap } | 监听原生标题栏按钮点击 | 仅 App 平台支持,e.index: 按钮索引 |
| onTabItemTap | onTabItemTap(item) | const onTabItemTap = (item) => {} 需导出:export default { onTabItemTap } | 点击 tab 时触发 | 小程序和 App 支持,item: {index, pagePath, text} |
| onResize | onResize() | const onResize = () => {} 需导出:export default { onResize } | 窗口尺寸变化 | 仅 H5 平台支持 |
| onThemeChange | onThemeChange(res) | const onThemeChange = (res) => {} 需导出:export default { onThemeChange } | 系统主题变化 | 小程序平台支持(微信、支付宝、百度),res.theme: 'light' 或 'dark' |
| onUniNViewMessage | onUniNViewMessage(event) | const onUniNViewMessage = (event) => {} 需导出:export default { onUniNViewMessage } | nvue 页面发送数据 | 仅 App-nvue 页面支持 |
| onSaveExitState | onSaveExitState() | const onSaveExitState = () => {} 需导出:export default { onSaveExitState } | 页面保存状态 | 仅 Android App支持,用于保存页面状态 |
| onNavigationBarSearchInputChanged | onNavigationBarSearchInputChanged(e) | const onNavigationBarSearchInputChanged = (e) => {} 需导出:export default { onNavigationBarSearchInputChanged } | 导航栏搜索输入内容变化 | 仅 App 和 H5支持,需在 pages.json 中配置 searchInput |
| onNavigationBarSearchInputConfirmed | onNavigationBarSearchInputConfirmed(e) | const onNavigationBarSearchInputConfirmed = (e) => {} 需导出:export default { onNavigationBarSearchInputConfirmed } | 导航栏搜索输入完成 | 仅 App 和 H5支持,需在 pages.json 中配置 searchInput |
| onNavigationBarSearchInputClicked | onNavigationBarSearchInputClicked(e) | const onNavigationBarSearchInputClicked = (e) => {} 需导出:export default { onNavigationBarSearchInputClicked } | 导航栏搜索输入框点击 | 仅 App 和 H5支持,需在 pages.json 中配置 searchInput |
| onNavigationBarSearchInputFocusChanged | onNavigationBarSearchInputFocusChanged(e) | const onNavigationBarSearchInputFocusChanged = (e) => {} 需导出:export default { onNavigationBarSearchInputFocusChanged } | 导航栏搜索输入框焦点变化 | 仅 App 和 H5支持,需在 pages.json 中配置 searchInput |
vue2执行流程
vue3执行流程
三、组件生命周期(与Vue相同)
beforeCreate:在实例初始化之后,数据观测和事件配置之前被调用created:在实例创建完成后被立即调用,此时数据观测、属性和方法的运算已完成,但DOM还未挂载beforeMount:在挂载开始之前被调用,相关的render函数首次被调用mounted:实例挂载到DOM之后调用,此时可以操作DOMbeforeUpdate:数据更新时调用,发生在虚拟DOM打补丁之前updated:由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用beforeDestroy:实例销毁之前调用,此时实例仍然完全可用destroyed:实例销毁后调用,所有的事件监听器会被移除,子实例也会被销毁
跳转方法
uni.navigateTo
uni.redirectTo
uni.reLaunch
uni.switchTab
uni.navigateBack
EventChannel
1. 正向传值(A页面 → B页面)
A页面(发送页面):
javascript
// 跳转时创建 EventChannel
uni.navigateTo({
url: '/pages/pageB/pageB',
events: {
// 监听来自B页面的事件
eventFromB: function(data) {
console.log('收到来自B页面的数据:', data)
}
},
success: function(res) {
// 向B页面发送事件
res.eventChannel.emit('eventFromA', {
data: '这是来自A页面的数据'
})
}
})
B页面(接收页面):
javascript
export default {
onLoad(options) {
// 获取 EventChannel
const eventChannel = this.getOpenerEventChannel()
// 监听来自A页面的事件
eventChannel.on('eventFromA', (data) => {
console.log('收到来自A页面的数据:', data)
})
// 向A页面发送事件
eventChannel.emit('eventFromB', {
data: '这是来自B页面的数据'
})
}
}
2. 接收返回数据(A页面 ← B页面)
A页面:
javascript
uni.navigateTo({
url: '/pages/pageB/pageB',
events: {
// 注册接收返回数据的事件
acceptDataFromB: function(data) {
console.log('接收到B页面返回的数据:', data)
}
}
})
B页面:
export default {
methods: {
// 返回数据到A页面
sendDataBack() {
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('acceptDataFromB', {
message: '操作成功',
result: '这里是B页面返回的数据'
})
uni.navigateBack()
}
}
}