在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生命周期钩子函数后被调用