index.ts 1.3 KB

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