apiLifecycle.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import {
  2. ComponentInstance,
  3. LifecycleHooks,
  4. currentInstance,
  5. setCurrentInstance,
  6. ComponentRenderProxy
  7. } from './component'
  8. import { callWithAsyncErrorHandling, ErrorTypeStrings } from './errorHandling'
  9. import { warn } from './warning'
  10. import { capitalize } from '@vue/shared'
  11. import { pauseTracking, resumeTracking } from '@vue/reactivity'
  12. function injectHook(
  13. type: LifecycleHooks,
  14. hook: Function,
  15. target: ComponentInstance | null
  16. ) {
  17. if (target) {
  18. ;(target[type] || (target[type] = [])).push((...args: any[]) => {
  19. // disable tracking inside all lifecycle hooks
  20. // since they can potentially be called inside effects.
  21. pauseTracking()
  22. // Set currentInstance during hook invocation.
  23. // This assumes the hook does not synchronously trigger other hooks, which
  24. // can only be false when the user does something really funky.
  25. setCurrentInstance(target)
  26. const res = callWithAsyncErrorHandling(hook, target, type, args)
  27. setCurrentInstance(null)
  28. resumeTracking()
  29. return res
  30. })
  31. } else if (__DEV__) {
  32. const apiName = `on${capitalize(
  33. ErrorTypeStrings[type].replace(/ hook$/, '')
  34. )}`
  35. warn(
  36. `${apiName} is called when there is no active component instance to be ` +
  37. `associated with. ` +
  38. `Lifecycle injection APIs can only be used during execution of setup().`
  39. )
  40. }
  41. }
  42. export function onBeforeMount(
  43. hook: Function,
  44. target: ComponentInstance | null = currentInstance
  45. ) {
  46. injectHook(LifecycleHooks.BEFORE_MOUNT, hook, target)
  47. }
  48. export function onMounted(
  49. hook: Function,
  50. target: ComponentInstance | null = currentInstance
  51. ) {
  52. injectHook(LifecycleHooks.MOUNTED, hook, target)
  53. }
  54. export function onBeforeUpdate(
  55. hook: Function,
  56. target: ComponentInstance | null = currentInstance
  57. ) {
  58. injectHook(LifecycleHooks.BEFORE_UPDATE, hook, target)
  59. }
  60. export function onUpdated(
  61. hook: Function,
  62. target: ComponentInstance | null = currentInstance
  63. ) {
  64. injectHook(LifecycleHooks.UPDATED, hook, target)
  65. }
  66. export function onBeforeUnmount(
  67. hook: Function,
  68. target: ComponentInstance | null = currentInstance
  69. ) {
  70. injectHook(LifecycleHooks.BEFORE_UNMOUNT, hook, target)
  71. }
  72. export function onUnmounted(
  73. hook: Function,
  74. target: ComponentInstance | null = currentInstance
  75. ) {
  76. injectHook(LifecycleHooks.UNMOUNTED, hook, target)
  77. }
  78. export function onRenderTriggered(
  79. hook: Function,
  80. target: ComponentInstance | null = currentInstance
  81. ) {
  82. injectHook(LifecycleHooks.RENDER_TRIGGERED, hook, target)
  83. }
  84. export function onRenderTracked(
  85. hook: Function,
  86. target: ComponentInstance | null = currentInstance
  87. ) {
  88. injectHook(LifecycleHooks.RENDER_TRACKED, hook, target)
  89. }
  90. export function onErrorCaptured(
  91. hook: (
  92. err: Error,
  93. instance: ComponentRenderProxy | null,
  94. info: string
  95. ) => boolean | void,
  96. target: ComponentInstance | null = currentInstance
  97. ) {
  98. injectHook(LifecycleHooks.ERROR_CAPTURED, hook, target)
  99. }