Vue3系列 - 生命周期钩子的实现

2025 年 9 月 2 日 星期二(已编辑)
/
3

Vue3系列 - 生命周期钩子的实现

生命周期钩子的实现

Vue3中的生命周期钩子与Vue2有所不同,它们以onXXX函数的形式提供,可以在setup函数中使用。Vue2.7也实现了这些钩子函数,让我们深入了解其实现原理。

生命周期钩子的创建

Vue2.7中的生命周期钩子是通过createLifeCycle函数创建的:

function createLifeCycle(hookName) {
  return (fn, target = currentInstance) => {
    if (!target) {
      __DEV__ &&
        warn(
          `${formatName(hookName)} is called when there is no active component instance to be ` +
            `associated with. ` +
            `Lifecycle injection APIs can only be used during execution of setup().`
        )
      return
    }
    return injectHook(target, hookName, fn)
  }
}

function formatName(name) {
  if (name === 'beforeDestroy') {
    name = 'beforeUnmount'
  } else if (name === 'destroyed') {
    name = 'unmounted'
  }
  return `on${name[0].toUpperCase() + name.slice(1)}`
}

function injectHook(instance, hookName, fn) {
  const options = instance.$options
  options[hookName] = mergeLifecycleHook(options[hookName], fn)
}

这段代码展示了生命周期钩子的创建过程:

  1. createLifeCycle返回一个函数,接受钩子函数和目标组件实例
  2. 检查是否有当前实例(确保在setup中调用)
  3. 通过injectHook将钩子函数注入到组件选项中
  4. mergeLifecycleHook确保多个相同类型的钩子都能被调用

生命周期钩子的定义

export const onBeforeMount = createLifeCycle('beforeMount')
export const onMounted = createLifeCycle('mounted')
export const onBeforeUpdate = createLifeCycle('beforeUpdate')
export const onUpdated = createLifeCycle('updated')
export const onBeforeUnmount = createLifeCycle('beforeDestroy')
export const onUnmounted = createLifeCycle('destroyed')
export const onActivated = createLifeCycle('activated')
export const onDeactivated = createLifeCycle('deactivated')
export const onServerPrefetch = createLifeCycle('serverPrefetch')

注意onBeforeUnmountonUnmounted内部使用的是Vue2的钩子名称('beforeDestroy'和'destroyed'),但对外提供了Vue3风格的API。

生命周期钩子的执行顺序

组件生命周期钩子的执行顺序是从父组件到子组件,然后再从子组件到父组件:

// 挂载阶段
parent beforeMount -> child beforeMount -> child mounted -> parent mounted

// 更新阶段
parent beforeUpdate -> child beforeUpdate -> child updated -> parent updated

// 卸载阶段
parent beforeUnmount -> child beforeUnmount -> child unmounted -> parent unmounted

这种执行顺序确保了子组件在父组件的上下文中正确初始化和销毁。

调试钩子

Vue3还引入了两个用于调试的钩子:

export const onRenderTracked = createLifeCycle<(e: DebuggerEvent) => any>('renderTracked')
export const onRenderTriggered = createLifeCycle<(e: DebuggerEvent) => any>('renderTriggered')

这些钩子可以帮助我们追踪组件渲染的依赖关系和触发原因。

总结

Vue2.7中的生命周期钩子实现了与Vue3相同的API,但内部仍然使用Vue2的生命周期机制。理解这些钩子的实现原理,有助于我们在正确的时机执行代码,避免常见的生命周期相关问题。组合式API中的生命周期钩子提供了更灵活的方式来组织组件逻辑,使代码更加模块化和可维护。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...