useParent.ts 842 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import {
  2. ref,
  3. inject,
  4. computed,
  5. onUnmounted,
  6. type InjectionKey,
  7. getCurrentInstance,
  8. type ComponentPublicInstance,
  9. type ComponentInternalInstance
  10. } from 'vue'
  11. type ParentProvide<T> = T & {
  12. link(child: ComponentInternalInstance): void
  13. unlink(child: ComponentInternalInstance): void
  14. children: ComponentPublicInstance[]
  15. internalChildren: ComponentInternalInstance[]
  16. }
  17. export function useParent<T>(key: InjectionKey<ParentProvide<T>>) {
  18. const parent = inject(key, null)
  19. if (parent) {
  20. const instance = getCurrentInstance()!
  21. const { link, unlink, internalChildren } = parent
  22. link(instance)
  23. onUnmounted(() => unlink(instance))
  24. const index = computed(() => internalChildren.indexOf(instance))
  25. return {
  26. parent,
  27. index
  28. }
  29. }
  30. return {
  31. parent: null,
  32. index: ref(-1)
  33. }
  34. }