index.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import { computed, getCurrentInstance, inject, unref } from 'vue'
  2. import { debugWarn, isClient } from '@kankan-components/utils'
  3. import { useGetDerivedNamespace } from '../use-namespace'
  4. import type { InjectionKey, Ref } from 'vue'
  5. import type { MaybeRef } from '@vueuse/core'
  6. export type ElIdInjectionContext = {
  7. prefix: number
  8. current: number
  9. }
  10. const defaultIdInjection = {
  11. prefix: Math.floor(Math.random() * 10000),
  12. current: 0,
  13. }
  14. export const ID_INJECTION_KEY: InjectionKey<ElIdInjectionContext> =
  15. Symbol('elIdInjection')
  16. export const useIdInjection = (): ElIdInjectionContext => {
  17. return getCurrentInstance()
  18. ? inject(ID_INJECTION_KEY, defaultIdInjection)
  19. : defaultIdInjection
  20. }
  21. export const useId = (deterministicId?: MaybeRef<string>): Ref<string> => {
  22. const idInjection = useIdInjection()
  23. if (!isClient && idInjection === defaultIdInjection) {
  24. debugWarn(
  25. 'IdInjection',
  26. `Looks like you are using server rendering, you must provide a id provider to ensure the hydration process to be succeed
  27. usage: app.provide(ID_INJECTION_KEY, {
  28. prefix: number,
  29. current: number,
  30. })`
  31. )
  32. }
  33. const namespace = useGetDerivedNamespace()
  34. const idRef = computed(
  35. () =>
  36. unref(deterministicId) ||
  37. `${namespace.value}-id-${idInjection.prefix}-${idInjection.current++}`
  38. )
  39. return idRef
  40. }