Uni-app 生命周期与钩子:程序的“生命”旅程

Uni-app 生命周期与钩子

你可以把一个 Uni-app 页面或组件想象成一个有生命的物体。从它被"出生"到"死亡",会经历一系列重要的阶段,每个阶段都有一些特定的"事情"会发生。这些"事情"就是我们说的"生命周期钩子"(或者叫"生命周期函数")。

通俗来说:生命周期钩子就是在页面或组件的特定时刻,你可以插入自己的代码来执行一些操作。

Uni-app 有两种主要的生命周期:

  1. 应用生命周期 (App Lifecycle): 整个小程序的生命。
  2. 页面生命周期 (Page Lifecycle): 某个"页面"的生命。
  3. 组件生命周期 (Component Lifecycle): 某个"组件"的生命(Vue3 Setup 风格下,组件生命周期和页面生命周期很多是共享的)。

一、应用生命周期 (App Lifecycle)

这指的是 整个 Uni-app 应用(小程序/H5/App) 的生命周期。它们在 App.vue 文件中定义。

onLaunch

什么时候触发?

最开始,App 第一次启动的时候。 整个应用只会触发一次。无论你从哪个页面进入、从小程序码、分享链接进入,都是第一次启动,就会调用。

常用场景?

  1. 获取用户信息或登录: 第一次启动时尝试静默登录,或者获取用户的基本信息(如 uni.login() 获取 code)。
  2. 全局配置初始化: 设置一些全局变量、主题配置等。
  3. 检查更新: 小程序如果有新版本,在这里提示用户。
  4. 加载全局数据: 比如从缓存中读取一些 App 级别的数据。

onShow

什么时候触发?

App 启动或从后台进入前台的时候。 比如你把小程序切到微信聊天界面,再切回来,就会触发。

常用场景?

  1. 统计用户活跃: 记录用户每次进入 App 的时间。
  2. 检查网络状态: 每次切回前台时,确保网络连接正常。
  3. 刷新数据: 如果你在后台修改了一些数据(比如个人信息),切回前台时可能需要刷新页面显示。
  4. 检查消息通知: 从后台切回时,检查是否有新的消息需要提示。

onHide

什么时候触发?

App 从前台进入后台的时候。 比如小程序切到微信聊天,或者点击了 Home 键。

常用场景?

  1. 保存数据: 用户离开时需要保存一些临时数据(如购物车状态、草稿)。
  2. 清除定时器: 停止一些不必要的后台运行,节省资源。
  3. 暂停音乐/视频播放。

onError

什么时候触发?

App 运行过程中发生错误的时候。 比如 JavaScript 运行时错误或网络请求失败。

常用场景?

  1. 错误监控和上报: 收集运行时的错误信息,发送到服务器进行分析和修复。

onPageNotFound

什么时候触发?

用户尝试打开一个不存在的页面路径。

常用场景?

  1. 自定义 404 页面: 可以重定向到首页或一个专门的错误页面,提升用户体验。

onUnhandledRejection

什么时候触发?

Promise 被拒绝,且没有 catch 处理器时触发。

常用场景?

  1. Promise 错误捕获: 统一处理 Promise 链中未被捕获的错误。

onThemeChange

什么时候触发?

用户切换主题时触发(深色模式/浅色模式)。仅微信小程序支持。

常用场景?

  1. 动态调整界面颜色: 根据用户选择的主题色,调整 App 的界面样式。

二、页面生命周期 (Page Lifecycle)

这指的是 某个具体页面 的生命周期。它们在每个 .vue 页面文件中定义(在 <script setup> 中直接导入或在 export default 中定义)。

onLoad(options)

什么时候触发?

页面第一次被加载的时候。 只会触发一次。options 里包含了页面跳转时传过来的参数(比如 uni.navigateTo({url: '/pages/detail?id=123'}),options.id 就是 123)。

常用场景?

  1. 获取页面参数: 读取传递到页面的数据,根据这些数据加载内容(比如商品详情页根据 ID 加载商品信息)。
  2. 一次性数据请求: 页面刚进来就需要的数据,而且不经常变化,只请求一次即可。
  3. 初始化页面状态: 设置页面标题、初始化表单数据等。

onShow

什么时候触发?

页面显示/活跃的时候。 每次进入页面(包括从其他页面回来、从后台切回前台)。

常用场景?

  1. 刷新数据: 最常用!比如从商品详情页返回列表页,需要刷新收藏状态;或者用户在其他地方修改了个人信息,回到个人中心需要刷新。
  2. 统计页面访问: 记录用户每次进入页面的行为。
  3. 清除定时器: 从后台切回页面时,可以恢复之前暂停的动画或定时器。

onReady

什么时候触发?

页面渲染完成的时候。 页面内容和组件都准备就绪,可以进行交互和操作了。

常用场景?

  1. 操作页面元素: 如果你需要获取页面上某个元素的高度、宽度,或者对 Canvas、Video 等组件进行操作,确保它们已经渲染完成。
  2. 启动动画: 在页面完全显示且稳定后,开始一些依赖布局的动画。

onHide

什么时候触发?

页面从前台进入后台的时候。 比如你从当前页面跳到另一个页面,或者把小程序/App 切到后台。

常用场景?

  1. 保存临时数据: 比如用户填写了一半的表单,可以暂时保存到缓存中,下次回来时恢复。这比在 onUnload 销毁前保存更安全。
  2. 停止不必要的活动: 比如停止视频播放、清除定时器、取消进行中的网络请求,避免资源浪费和性能问题。

onUnload

什么时候触发?

页面被销毁的时候。 比如用户点击返回按钮退出了这个页面,或者调用 uni.redirectTo、uni.reLaunch 跳转到其他页面时,当前页面就会被销毁。

常用场景?

  1. 清理资源: 清除所有监听器、定时器、WebSocket 连接等,防止内存泄漏。这是必须做的,确保程序干净地退出。
  2. 保存最终数据: 页面销毁前必须保存的数据(比如用户在当前页面完成的特定操作结果)。

onPullDownRefresh

什么时候触发?

用户下拉刷新页面的时候。 需要在 pages.json 或 uni.setNavigationBarTextStyle 中开启 "enablePullDownRefresh": true。

常用场景?

  1. 刷新当前页面数据: 比如在商品列表页下拉刷新,重新请求商品数据。
  2. uni.stopPullDownRefresh() : 刷新完成后,一定要调用这个方法,否则加载动画会一直转。

onReachBottom

什么时候触发?

页面滚动到底部的时候。

常用场景?

  1. 加载更多数据: 比如在列表页滚动到底部时,加载下一页的内容(实现"上拉加载")。
  2. 防止重复加载: 在请求数据时设置一个标志位,防止在数据还没回来时用户再次触发底部加载。

onShareAppMessage(options)

什么时候触发?

用户点击右上角菜单的"转发"按钮,或点击页面内 <button open-type="share"></button> 按钮时触发。

常用场景?

  1. 自定义转发内容 : 配置转发的标题、图片、路径等。可以根据 options.from 判断是"按钮"还是"菜单"触发的。必须返回一个对象,否则无法分享。

onShareTimeline()

什么时候触发?

用户点击右上角菜单的"分享到朋友圈"按钮时触发。仅微信小程序支持。

常用场景?

  1. 自定义分享朋友圈内容 : 配置分享到朋友圈的标题、查询参数(不能有图片)。必须返回一个对象,否则无法分享。

onPageScroll(object)

什么时候触发?

页面滚动时触发。 object.scrollTop 表示当前滚动的距离。

常用场景?

  1. 吸顶效果: 根据滚动距离改变导航栏或某个组件的样式(比如固定在顶部)。
  2. 返回顶部按钮: 当滚动到一定距离时显示返回顶部按钮。

onResize(object)

什么时候触发?

页面尺寸改变时触发,比如横竖屏切换。App(含 H5)支持。小程序仅在 wx.onWindowResize 回调中返回。

常用场景?

  1. 响应式布局调整: 根据页面宽高调整布局或组件显示。

onTabItemTap(object)

什么时候触发?

点击 TabBar 上的某个 TabItem 时触发(即使当前就是该页)。object 包含当前 TabItem 的文本、索引、图标路径等信息。

常用场景?

  1. Tab 页面二次点击刷新: 当用户点击当前激活的 Tab 时,可以实现"点击两次刷新页面"的效果。
  2. Tab 切换统计

onBackPress(options) (+uni.navigateBack)

什么时候触发?

用户点击左上角返回按钮,或者用手机自带的返回键返回时触发。在 options.from 为 backbutton 时才生效,其他情况会默认返回。仅 App 和 H5 支持。 微信小程序使用 uni.navigateBack 监听。

常用场景?

  1. 阻止返回: 当有重要操作未完成或表单未保存时,提示用户是否确定退出,避免数据丢失。
  2. 自定义返回行为: 不直接返回,而是跳转到其他页面。return true 可阻止默认返回行为。

onNavigationBarButtonTap(object)

什么时候触发?

点击页面右上角导航栏按钮时触发。这些按钮通过 pages.json navigationStyle: custom 或 `uni

常用场景?

  1. 添加/新建功能: 比如在列表页的右上角放置一个"+"号按钮,点击后跳转到新建页面。
  2. 筛选/排序: 在数据列表页右上角放置一个筛选或排序的图标,点击后弹出筛选条件。
  3. 分享/操作菜单: 放置一个三个点(更多)图标,点击后显示一个操作菜单。
  4. 自定义行为: 根据业务需求,在导航栏提供快速入口,执行特定的页面内操作。

三、组件生命周期 (Component Lifecycle) - Vue 3 Composition API

setup()

什么时候触发?

这是 script setup 模式的特殊处理。所有在 <script setup> 标签内直接声明的变量、函数、ref、reactive 以及执行的逻辑(不包括包裹在 onMounted 等钩子里的代码),都会在组件实例化时 同步执行 。它发生在组件数据响应化处理之后,DOM 挂载之前。 相当于 Vue 2 的 beforeCreate 和 created 阶段的结合。

常用场景?

  1. 声明响应式状态: const count = ref(0);、const state = reactive({ name: 'Vue' });
  2. 定义计算属性和侦听器: const doubledCount = computed(() => count.value * 2);、watch(count, (newVal) => { ... });
  3. 非 DOM 依赖的数据请求: 在组件渲染前就需要的初始化数据请求(如 uni.request),因为这些数据通常不需要等到 DOM 挂载。
  4. 注册非 DOM 相关事件监听器: 例如 uni.$on 发布的自定义事件。

onBeforeMount(() => { ... })

什么时候触发?

组件的模板已经被编译成渲染函数,但尚未挂载到真实的 DOM 元素上。 此时可以访问到 ref 和 reactive 数据,但无法访问或操作真实的 DOM。

常用场景?

很少使用。 在这个阶段没有太多可操作的 DOM 相关的逻辑。如果你需要在 DOM 挂载之前对响应式数据进行一些最终的调整,可以使用。

onMounted(() => { ... })

什么时候触发?

组件被挂载到页面上,真实的 DOM 已经渲染完成。 你可以访问和操作组件的真实 DOM 元素了(例如通过 uni.createSelectorQuery 查询元素信息)。组件中的子组件也可能已经挂载。

常用场景?

  1. DOM 操作: 获取组件的大小、位置,或对 Canvas、Video、Map 等需要实际渲染后才能操作的组件进行初始化或操作。例如,通过 uni.createSelectorQuery().select('#myElement').boundingClientRect() 获取元素尺寸。
  2. 启动动画: 依赖真实 DOM 存在的动画效果,确保动画作用的元素已经就位。
  3. 第三方库初始化: 如果组件使用了需要挂载后才能初始化的第三方库(如一些图表库、地图SDK),应在此处进行初始化。
  4. 首次聚焦输入框: 确保输入框在页面渲染后自动获取焦点。

onBeforeUpdate(() => { ... })

什么时候触发?

响应式数据发生变化,准备重新渲染 DOM 之前。 此时 DOM 尚未更新,你仍然可以访问到旧的 DOM 状态和更新前的响应式数据。

常用场景?

很少使用。 可以在这里获取更新前的数据状态,或者在 DOM 更新前进行一些清理操作。例如,如果你需要手动管理滚动位置,可以在这里保存当前位置,然后在 onUpdated 中恢复。

onUpdated(() => { ... })

什么时候触发?

响应式数据变化导致组件内容重新渲染完成(真实的 DOM 已根据新数据更新)。

常用场景?

  1. DOM 更新后操作: 当组件数据更新,并且 DOM 视图已根据新数据重新渲染完毕后,进行一些依赖最新 DOM 状态的操作。例如,在列表数据更新后,调整滚动位置或重新计算某些元素的尺寸。
  2. 动画处理: 当某些数据显示出来后,启动与之相关的动画。

onBeforeUnmount(() => { ... })

什么时候触发?

组件实例销毁之前。 组件仍然可用,事件监听器和子组件都还未被销毁。这是清除"副作用"前的最后机会。

常用场景?

onUnmounted(() => { ... })

什么时候触发?

  1. 保存临时状态: 在组件被卸载前,保存一些用户输入、滚动位置、播放进度等临时数据(到 Vuex/Pinia 或本地存储)。
  2. 清除组件内部的监听器: 如果你在组件内部手动注册了一些 uni.onXxx 的监听,可以在这里提前取消,避免在 onUnmounted 中再处理,也避免在子组件销毁前就触发一些不必要的逻辑。

常用场景?

onErrorCaptured((err, instance, info) => { ... })

什么时候触发?

当捕获到来自子组件或自身组件树中后代组件的错误时调用。 err 是错误对象,instance 是触发错误的组件实例,info 是错误源信息。

常用场景?

  1. 错误边界: 类似于 React 的 Error Boundary。捕获并处理子组件的错误,防止整个应用崩溃。可以显示一个错误提示界面,提供重试选项,或者向上级组件报告错误。
  2. 错误日志: 将捕获到的错误上报到错误监控平台。
  • 本文仅作个人学习笔记使用,无商业用途。
  • 如若转载,请先声明。
相关推荐
一斤代码1 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
qq_424409193 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
2501_915918413 小时前
Fiddler中文版全面评测:功能亮点、使用场景与中文网资源整合指南
android·ios·小程序·https·uni-app·iphone·webview
不知名It水手5 小时前
uniapp运行项目到ios基座
ios·uni-app·cocoa
hunzi_15 小时前
搭建商城系统
java·uni-app·php
sunbyte6 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DoubleVerticalSlider(双垂直滑块)
前端·javascript·css·vue.js·vue
合作小小程序员小小店8 小时前
web网页,在线%食谱推荐系统%分析系统demo,基于vscode,uniapp,vue,java,jdk,springboot,mysql数据库
vue.js·spring boot·vscode·spring·uni-app
CRMEB定制开发11 小时前
CRMEB Pro版前端环境配置指南
前端·微信小程序·uni-app·商城源码·微信商城·crmeb
你喜欢喝可乐吗?14 小时前
RuoYi-Cloud 验证码处理流程
java·spring cloud·微服务·vue