apiInject.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. import { currentInstance } from './component'
  2. import { warn } from './warning'
  3. export interface InjectionKey<T> extends Symbol {}
  4. export function provide<T>(key: InjectionKey<T> | string, value: T) {
  5. if (!currentInstance) {
  6. if (__DEV__) {
  7. warn(`provide() can only be used inside setup().`)
  8. }
  9. } else {
  10. let provides = currentInstance.provides
  11. // by default an instance inherits its parent's provides object
  12. // but when it needs to provide values of its own, it creates its
  13. // own provides object using parent provides object as prototype.
  14. // this way in `inject` we can simply look up injections from direct
  15. // parent and let the prototype chain do the work.
  16. const parentProvides =
  17. currentInstance.parent && currentInstance.parent.provides
  18. if (parentProvides === provides) {
  19. provides = currentInstance.provides = Object.create(parentProvides)
  20. }
  21. provides[key as any] = value
  22. }
  23. }
  24. export function inject<T>(key: InjectionKey<T> | string): T | undefined
  25. export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
  26. export function inject(key: InjectionKey<any> | string, defaultValue?: any) {
  27. if (currentInstance) {
  28. const provides = currentInstance.provides
  29. if (key in provides) {
  30. return provides[key as any] as any
  31. } else if (defaultValue !== undefined) {
  32. return defaultValue
  33. } else if (__DEV__) {
  34. warn(`injection "${key}" not found.`)
  35. }
  36. } else if (__DEV__) {
  37. warn(`inject() can only be used inside setup().`)
  38. }
  39. }