Vue 3 生命周期钩子全面解析:组合式 API 与传统选项式的差异

Vue 3 的发布带来了全新的组合式 API,不仅改变了代码组织方式,也重新设计了生命周期钩子的使用形式。对于从 Vue 2 迁移过来的开发者,理解生命周期钩子在选项式 API 与组合式 API 中的差异,是掌握 Vue 3 的关键一步。本文将系统梳理 Vue 3 中的生命周期钩子,对比两种 API 风格的写法、执行时机与适用场景,并给出迁移建议与最佳实践。

一、Vue 3 生命周期钩子概览

无论使用哪种 API 风格,Vue 3 组件实例的生命周期都包含以下主要阶段:

  • 创建阶段beforeCreatecreated
  • 挂载阶段beforeMountmounted
  • 更新阶段beforeUpdateupdated
  • 卸载阶段beforeUnmountunmounted
  • 错误处理errorCaptured
  • 其他activateddeactivated(KeepAlive 缓存组件)、renderTrackedrenderTriggered(开发调试)

与 Vue 2 相比,Vue 3 将 beforeDestroydestroyed 重命名为 beforeUnmountunmounted,语义更准确。同时,组合式 API 中新增了 onRenderTrackedonRenderTriggered 两个调试钩子。

二、选项式 API 中的生命周期钩子

选项式 API 延续了 Vue 2 的写法,将生命周期钩子作为组件选项直接定义:

export default {
  data() {
    return { count: 0 }
  },
  beforeCreate() {
    console.log('beforeCreate')
  },
  created() {
    console.log('created')
  },
  beforeMount() {
    console.log('beforeMount')
  },
  mounted() {
    console.log('mounted')
  },
  beforeUpdate() {
    console.log('beforeUpdate')
  },
  updated() {
    console.log('updated')
  },
  beforeUnmount() {
    console.log('beforeUnmount')
  },
  unmounted() {
    console.log('unmounted')
  }
}

选项式 API 的优点是直观、易于理解,所有钩子都平铺在组件选项中,适合小型组件或初学者。但缺点是逻辑分散:同一个功能相关的代码可能被拆分到 datamethodsmounted 等多个选项中,导致组件难以维护。

三、组合式 API 中的生命周期钩子

组合式 API 通过 setup 函数或 <script setup> 语法糖使用生命周期钩子。所有钩子都需要从 vue 中显式导入,并以 on 开头:

import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from 'vue'

export default {
  setup() {
    onBeforeMount(() => {
      console.log('onBeforeMount')
    })
    onMounted(() => {
      console.log('onMounted')
    })
    onBeforeUpdate(() => {
      console.log('onBeforeUpdate')
    })
    onUpdated(() => {
      console.log('onUpdated')
    })
    onBeforeUnmount(() => {
      console.log('onBeforeUnmount')
    })
    onUnmounted(() => {
      console.log('onUnmounted')
    })
  }
}

<script setup> 中写法更简洁:

<script setup>
import { onMounted, onUnmounted } from 'vue'

onMounted(() => {
  console.log('组件已挂载')
})

onUnmounted(() => {
  console.log('组件已卸载')
})
</script>

组合式 API 的对应关系

选项式 API 组合式 API
beforeCreate 不需要,直接写在 setup 中
created 不需要,直接写在 setup 中
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
activated onActivated
deactivated onDeactivated
renderTracked onRenderTracked
renderTriggered onRenderTriggered

注意:beforeCreatecreated 在组合式 API 中没有对应的钩子,因为 setup 本身就在这两个阶段之间执行,所有同步代码都相当于在这两个阶段运行。

四、核心差异对比

1. 执行时机与调用顺序

在选项式 API 中,生命周期钩子按照固定顺序执行。在组合式 API 中,钩子的注册顺序决定了执行顺序。例如,多个 onMounted 会按照注册顺序依次执行:

onMounted(() => console.log('第一个'))
onMounted(() => console.log('第二个'))
// 输出:第一个、第二个

此外,组合式 API 中如果使用了多个 setup(如混入),钩子的执行顺序也遵循注册顺序,而非选项式 API 中的合并策略。

2. 代码组织与逻辑复用

组合式 API 最大的优势是逻辑复用。通过自定义组合函数,可以将相关的生命周期逻辑封装在一起:

// useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  function update(e) {
    x.value = e.pageX
    y.value = e.pageY
  }

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  return { x, y }
}

在组件中使用:

<script setup>
import { useMouse } from './useMouse'
const { x, y } = useMouse()
</script>

这种模式在选项式 API 中只能通过 mixin 实现,但 mixin 存在命名冲突、来源不清晰等问题。组合式 API 从根本上解决了这些痛点。

3. this 的访问

选项式 API 中,生命周期钩子可以通过 this 访问组件实例。组合式 API 中,setup 内没有 this,需要通过 refgetCurrentInstance 访问。官方建议尽量避免使用 getCurrentInstance,而是通过组合函数显式传递依赖。

4. 异步操作的处理

在组合式 API 中,setup 可以是异步函数(需配合 <Suspense>),但生命周期钩子必须在 setup 同步执行期间注册。如果在 await 之后注册钩子,将无法正确绑定到当前组件实例。因此,推荐将异步逻辑放在 onMounted 中:

onMounted(async () => {
  const data = await fetchData()
})

五、迁移建议与最佳实践

  1. 新项目优先使用组合式 API:尤其是 <script setup>,代码更简洁,类型推断更友好。
  2. 旧项目渐进迁移:选项式 API 在 Vue 3 中完全支持,可以逐步将复杂组件改写为组合式 API。
  3. 避免在 setup 中滥用生命周期:能用 watchwatchEffect 或计算属性解决的问题,不要强行放入生命周期钩子。
  4. 清理副作用:在 onUnmounted 中清除定时器、事件监听、订阅等,防止内存泄漏。
  5. 注意 SSR 兼容onMounted 在服务端渲染中不会执行,涉及 DOM 的操作应放在 onMounted 中。

六、总结

Vue 3 的生命周期钩子在选项式 API 中基本保持了 Vue 2 的形态,仅将销毁相关钩子重命名;而在组合式 API 中,钩子以 on 前缀的函数形式出现,需要显式导入,并与 setup 逻辑紧密结合。组合式 API 在逻辑复用、代码组织和类型支持方面具有明显优势,是 Vue 3 推荐的开发方式。理解两种 API 的差异,有助于开发者根据项目需求灵活选择,并顺利从 Vue 2 迁移到 Vue 3。

未经允许不得转载:任鹏个人博客 » Vue 3 生命周期钩子全面解析:组合式 API 与传统选项式的差异

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏