Skip to content

在vue源码lifecycle.ts文件下有这么一个方法:
callHook函数在执行完生命周期钩子函数(invokeWithErrorHandling)后会执行hook:xxx事件

js
function callHook(vm, hook) {
  const handlers = vm.$options[hook]
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, args || null, vm, info)
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
}
function callHook(vm, hook) {
  const handlers = vm.$options[hook]
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, args || null, vm, info)
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
}
js
export function invokeWithErrorHandling(
    handler: Function,
    context: any,
    args: null | any[],
    vm: any,
    info: string
) {
    let res
    try {
        res = args ? handler.apply(context, args) : handler.call(context)
        if (res && !res._isVue && isPromise(res) && !(res)._handled) {
            res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
        }
    } catch (e: any) {
        handleError(e, vm, info)
    }
    return res
}
export function invokeWithErrorHandling(
    handler: Function,
    context: any,
    args: null | any[],
    vm: any,
    info: string
) {
    let res
    try {
        res = args ? handler.apply(context, args) : handler.call(context)
        if (res && !res._isVue && isPromise(res) && !(res)._handled) {
            res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
        }
    } catch (e: any) {
        handleError(e, vm, info)
    }
    return res
}

在callHook函数中遍历handlers(生命周期钩子函数数组),遍历至每一项时会执行函数:invokeWithErrorHandling(handlers[i], vm, args || null, vm, info) 如果是子组件初始化,会执行initInternalComponent(vm, options as any) ,并且生命周期钩子函数数组会挂载在vm.$options原型链上

提示

例如我们要在父组件中监听子组件mounted钩子函数执行完,我们可以这样做:
1、子组件与父组件通过$on与$emit进行发布订阅
2、在子组件上注册hook:xxx事件:<compontent @hook:mounted="action" />,action事件会在执行完mounted生命周期钩子函数后被调用