1. 理解生命周期的基本概念

如果你刚接触uniapp和Vue3,可能会对"生命周期"这个词感到困惑。简单来说,生命周期就像一个人的成长阶段:出生、上学、工作、退休。在代码世界里,组件和页面也有自己的"人生轨迹"——从创建到销毁的完整过程。

在Vue3中,生命周期函数就是这些关键节点的"闹钟提醒"。比如组件刚创建时(setup)、挂载到页面时(onMounted)、数据更新时(onUpdated)等,都会触发对应的回调函数。这就像装修房子:打地基时(setup)要规划水电,刷墙时(onMounted)要选涂料,家具进场后(onUpdated)还要调整布局。

uniapp作为跨平台框架,在此基础上增加了页面级生命周期。比如微信小程序里的页面切换场景:当你从首页跳转到详情页时,首页会触发onHide(暂时隐藏),详情页会触发onLoad(初次加载)。这种设计让开发者能精准控制不同平台下的页面行为。

2. Vue3组合式API下的生命周期

2.1 核心钩子函数解析

用Vue3的<script setup>写法时,生命周期函数需要从vue显式导入:

import { onMounted, onUpdated } from 'vue'

常用钩子函数及其使用场景:

  • onBeforeMount:组件挂载前最后一刻。适合操作DOM(比如初始化echarts容器)
  • onMounted:组件已挂载。这里可以安全访问DOM元素(实测在小程序里获取节点信息要在这里操作)
  • onBeforeUpdate:数据变化导致DOM更新前。我曾经在这里记录滚动位置,更新后恢复
  • onUnmounted:组件卸载时。必须在这里清除定时器、解绑全局事件,否则会导致内存泄漏

注意:uniapp小程序环境中,onBeforeUpdate和onUpdated可能不生效,建议用watch替代数据变化监听

2.2 setup的特殊地位

setup()是Vue3的组合式API核心,它比传统的beforeCreate更早执行。这意味着:

  1. 在这里无法访问this(组件实例尚未创建)
  2. 所有响应式数据、方法都需要在setup中定义
// 正确的setup用法
const count = ref(0)
onMounted(() => {
  console.log('计数器初始值:', count.value)
})

3. uniapp专属页面生命周期

3.1 关键页面钩子

uniapp的页面生命周期需要从特定模块导入:

import { onLoad, onShow } from '@dcloudio/uni-app'

各钩子的典型应用场景:

  • onLoad:接收页面参数。比如商品详情页获取商品ID后请求接口
  • onShow:每次页面显示时触发。适合刷新列表数据(比如购物车返回时价格更新)
  • onReady:初次渲染完成。可以在这里操作DOM(比如初始化地图组件)

3.2 跨平台差异处理

不同平台的生命周期表现可能不同:

  • 微信小程序切换tab页时,原页面不会触发onUnload,只会onHide
  • APP端页面预加载可能导致onLoad提前执行
  • H5端浏览器后退按钮可能跳过部分生命周期

解决方案示例:

// 统一处理页面显示时的数据刷新
onShow(() => {
  if (needRefresh.value) {
    loadData()
  }
})

4. 生命周期执行顺序实战

4.1 无组件页面的流程

通过一个待办事项列表页的加载过程演示:

  1. onLoad:获取路由参数,初始化空数组
  2. onShow:检查本地缓存是否有待办数据
  3. onReady:隐藏加载动画,此时页面已可交互
// todoList页面示例
onLoad(async (options) => {
  todoId.value = options.id
  loading.value = true
})

onShow(async () => {
  if (!dataLoaded.value) {
    await fetchTodoList()
  }
})

4.2 含组件页面的完整流程

当页面包含子组件时(比如一个日期选择器组件),执行顺序变为:

  1. 页面onLoad → onShow
  2. 组件setup → onBeforeMount
  3. 页面onReady
  4. 组件onMounted

这个顺序意味着:在页面的onReady中操作子组件DOM可能会失败,因为子组件可能尚未挂载完成。我曾在项目中因此踩坑,最终解决方案是用nextTick:

onMounted(() => {
  nextTick(() => {
    // 此时保证子组件已完成渲染
    initCalendar()
  })
})

5. 常见问题与性能优化

5.1 生命周期滥用陷阱

新手常犯的错误包括:

  • 在onMounted中频繁更新数据导致无限循环
  • 忘记在onUnmounted清除全局事件监听
  • 在onLoad执行耗时同步操作导致页面卡顿

优化建议:

  • 耗时操作放入setTimeout或使用Promise异步处理
  • 使用keep-alive缓存页面时,用onActivated替代onShow处理数据刷新

5.2 调试技巧

在Chrome开发者工具中,可以通过以下方式观察生命周期:

  1. 在生命周期函数内打debugger断点
  2. 使用Vue Devtools的Timeline功能
  3. 简单粗暴的console.log标记(适合真机调试)
onMounted(() => {
  console.log('[生命周期日志] 组件挂载完成')
  debugger // 主动触发断点
})

实际开发中,理解生命周期就像掌握交通规则——知道每个"路口"(钩子函数)该做什么,才能让代码流畅运行不"堵车"。建议在初期多写demo验证执行顺序,熟悉后就能自然写出更健壮的应用架构。

更多推荐