组合式 API:生命周期钩子 {#composition-api-lifecycle-hooks}

:::info 使用方式注意 所有罗列在本页的 API 都应该在组件的 setup() 阶段被同步调用。相关细节请看 指南 - 生命周期钩子。 :::

onMounted() {#onmounted}

注册一个在组件挂载完成后执行的回调函数。

  • 类型

    1. function onMounted(callback: () => void): void
  • 详细信息

    组件在以下情况下被视为已挂载:

    • 它的所有同步子组件都已经被挂载(不包含异步组件或 <Suspense> 树内的组件)。

    • 它的 DOM 树已被创建并插入到父容器中。注意,只有当应用程序的根容器也在文档中时,它才能保证组件的 DOM 树在文档中。

    这个钩子常常用于需要访问到组件已经渲染好的 DOM 元素之时,或是为了在一个 服务端渲染应用 中限制 DOM 相关的代码。

    这个钩子在服务器端渲染期间不会被调用。

  • 示例

    通过模板 ref 访问一个元素:

    1. <script setup>
    2. import { ref, onMounted } from 'vue'
    3. const el = ref()
    4. onMounted(() => {
    5. el.value // <div>
    6. })
    7. </script>
    8. <template>
    9. <div ref="el"></div>
    10. </template>

onUpdated() {#onupdated}

注册一个回调函数,在组件由于响应性状态改变而更新了 DOM 树后调用。

  • 类型

    1. function onUpdated(callback: () => void): void
  • 详细信息

    父组件的更新钩子会在其子组件的更新钩子之后被调用。

    这个钩子在组件的任何 DOM 更新之后被调用,这可能是由不同的状态变化引起的。请如果你需要在一个特定的状态改变后访问更新好的 DOM,使用 nextTick() 替代。

    这个钩子在服务器端渲染期间不会被调用。

    :::warning 不要在更新的钩子中突变组件的状态,这很可能会导致无限的更新循环。 :::

  • 示例

    访问更新后的 DOM

    1. <script setup>
    2. import { ref, onUpdated } from 'vue'
    3. const count = ref(0)
    4. onUpdated(() => {
    5. // 文本内哦让应该与当前的 `count.value` 一致
    6. console.log(document.getElementById('count').textContent)
    7. })
    8. </script>
    9. <template>
    10. <button id="count" @click="count++">{{ count }}</button>
    11. </template>

onUnmounted() {#onunmounted}

注册一个要在组件卸载后调用的回调。

  • 类型

    1. function onUnmounted(callback: () => void): void
  • 详细信息

    组件在以下情况下被认为是卸载的:

    • 它的所有子组件都已卸载。

    • 所有相关的响应式副作用(渲染效果和在 setup() 期间创建的计算属性/侦听器)都已经停止。

    可以使用此钩子清除手动创建的副作用,如定时器、DOM事件监听器或服务器连接。

    这个钩子在服务器端渲染期间不会被调用。

  • 示例

    1. <script setup>
    2. import { onMounted, onUnmounted } from 'vue'
    3. let intervalId
    4. onMounted(() => {
    5. intervalId = setInterval(() => {
    6. // ...
    7. })
    8. })
    9. onUnmounted(() => clearInterval(intervalId))
    10. </script>

onBeforeMount() {#onbeforemount}

注册一个钩子在组件被挂载之前被调用。

  • 类型

    1. function onBeforeMount(callback: () => void): void
  • 详细信息

    当这个钩子被调用时,组件已经完成了其响应状态的设置,但是还没有创建 DOM 节点。它将第一次执行 DOM 渲染效果。

    这个钩子在服务器端渲染期间不会被调用。

onBeforeUpdate() {#onbeforeupdate}

注册一个钩子,在组件因为响应式状态改变而要更新 DOM 树之前调用。

  • 类型

    1. function onBeforeUpdate(callback: () => void): void
  • 详细信息

    这个钩子可以在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中修改组件状态也是安全的。

    这个钩子在服务器端渲染期间不会被调用。

onBeforeUnmount() {#onbeforeunmount}

注册一个钩子,在组件实例被卸载之前调用。

  • 类型

    1. function onBeforeUnmount(callback: () => void): void
  • 详细信息

    当这个钩子被调用时,组件实例的功能仍然是完整的。

    这个钩子在服务器端渲染期间不会被调用。

onErrorCaptured() {#onerrorcaptured}

注册一个钩子,当从下级组件抛上来的错误被捕获时被调用。

  • 类型

    1. function onErrorCaptured(callback: ErrorCapturedHook): void
    2. type ErrorCapturedHook = (
    3. err: unknown,
    4. instance: ComponentPublicInstance | null,
    5. info: string
    6. ) => boolean | void
  • 详细信息

    错误可以从以下来源捕获:

    • 组件渲染
    • 事件处理器
    • 生命周期钩子
    • setup() 函数
    • 侦听器
    • 自定义指令钩子
    • 过渡钩子

    该钩子接收三个参数:错误对象、触发该错误的组件实例和指定错误源类型的信息字符串。

    你可以在 errorCaptured() 之中改变组件状态来展示一个错误给用户。然而,更重要的是,错误状态不应该呈现导致错误的原始内容。否则,组件将被扔进一个无限渲染循环。

    若在此钩子中返回 false 则会阻止错误继续传播。见下面的错误传播细节描述。

    错误传播规则

    • 默认情况下,所有的错误都会一直向上抛,直到被应用级的 app.config.errorHandler 捕获(前提是这个处理函数已被定义)。这样所有的错误都可以被上报给一处统计服务用于分析。

    • 如果有多个 errorCaptured 钩子存在于一个组件的继承链或父组件链上,那么对同一个错误,它们中每一个都会被调用。

    • 如果该 errorCaptured 钩子自己也抛出了一个错误,则会和之前捕获到的错误一起被上抛至 app.config.errorHandler

    • 一个 errorCaptured 钩子可以返回 false 来阻止错误继续传播。这实际上就是在说“这个错误已经被处理,可以被忽略”。它会组织任何其他的 errorCaptured 钩子或 app.config.errorHandler 对此错误进行调用。

onRenderTracked() {#onrendertracked}

注册一个调试钩子,当组件的渲染效果跟踪了一个响应性依赖时调用。

这个钩子仅在开发模式下可用,且在服务器端渲染期间不会被调用。

  • 类型

    1. function onRenderTracked(callback: DebuggerHook): void
    2. type DebuggerHook = (e: DebuggerEvent) => void
    3. type DebuggerEvent = {
    4. effect: ReactiveEffect
    5. target: object
    6. type: TrackOpTypes /* 'get' | 'has' | 'iterate' */
    7. key: any
    8. }
  • 相关内容: Reactivity in Depth

onRenderTriggered() {#onrendertriggered}

注册一个调试钩子,当响应性依赖触发组件的渲染效果重新运行时调用。

这个钩子仅在开发模式下可用,且在服务器端渲染期间不会被调用。

  • 类型

    1. function onRenderTriggered(callback: DebuggerHook): void
    2. type DebuggerHook = (e: DebuggerEvent) => void
    3. type DebuggerEvent = {
    4. effect: ReactiveEffect
    5. target: object
    6. type: TriggerOpTypes /* 'set' | 'add' | 'delete' | 'clear' */
    7. key: any
    8. newValue?: any
    9. oldValue?: any
    10. oldTarget?: Map<any, any> | Set<any>
    11. }
  • 相关内容: Reactivity in Depth

onActivated() {#onactivated}

注册一个回调函数,当组件实例作为树的一部分被 <KeepAlive> 缓存,被插入到 DOM 中时调用。

这个钩子在服务器端渲染期间不会被调用。

onDeactivated() {#ondeactivated}

注册一个回调函数,当组件实例作为树的一部分被 <KeepAlive> 缓存,从 DOM 中移除时调用。

这个钩子在服务器端渲染期间不会被调用。

onServerPrefetch() {#onserverprefetch}

在组件实例在服务器上渲染之前,注册一个要完成的异步函数。

  • 类型

    1. function onServerPrefetch(callback: () => Promise<any>): void
  • 详细信息

    如果回调返回一个Promise,服务器渲染器将在渲染组件之前等待,直到 Promise 完成。

    这个钩子只在服务器端渲染期间被调用,可以用来抓取服务器相关的数据。

  • 示例

    1. <script setup>
    2. import { ref, onServerPrefetch, onMounted } from 'vue'
    3. const data = ref(null)
    4. onServerPrefetch(async () => {
    5. // 组件作为初始请求的一部分被渲染
    6. // 在服务器上预抓取数据,因为它比在客户端上更快。
    7. data.value = await fetchOnServer(/* ... */)
    8. })
    9. onMounted(async () => {
    10. if (!data.value) {
    11. // 如果数据在挂载时为空值,这意味着该组件
    12. // 是在客户端动态渲染的。将转而执行
    13. // 一个客户端侧的抓取请求
    14. data.value = await fetchOnClient(/* ... */)
    15. }
    16. })
    17. </script>
  • 相关内容: 服务端渲染