import { DebuggerEvent } from './debug' import { Component } from 'types/component' import { mergeLifecycleHook, warn } from '../core/util' import { currentInstance } from './currentInstance' function createLifeCycle any = () => void>( hookName: string ) { return (fn: T, target: any = 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: string) { if (name === 'beforeDestroy') { name = 'beforeUnmount' } else if (name === 'destroyed') { name = 'unmounted' } return `on${name[0].toUpperCase() + name.slice(1)}` } function injectHook(instance: Component, hookName: string, fn: () => void) { const options = instance.$options options[hookName] = mergeLifecycleHook(options[hookName], fn) } 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') export const onRenderTracked = createLifeCycle<(e: DebuggerEvent) => any>('renderTracked') export const onRenderTriggered = createLifeCycle<(e: DebuggerEvent) => any>('renderTriggered') export type ErrorCapturedHook = ( err: TError, instance: any, info: string ) => boolean | void const injectErrorCapturedHook = createLifeCycle>('errorCaptured') export function onErrorCaptured( hook: ErrorCapturedHook, target: any = currentInstance ) { injectErrorCapturedHook(hook, target) }