element-plus/packages/hooks/use-id/index.ts
btea 105d79b0d9
refactor: extract isClient and isNumber isBoolean (#12504)
* refactor: extract isClient and isNumber isBoolean

* test: update test

* refactor: extract isClient to browser
2023-04-20 20:00:49 +08:00

49 lines
1.3 KiB
TypeScript

import { computed, getCurrentInstance, inject, unref } from 'vue'
import { debugWarn, isClient } from '@element-plus/utils'
import { useGetDerivedNamespace } from '../use-namespace'
import type { InjectionKey, Ref } from 'vue'
import type { MaybeRef } from '@vueuse/core'
export type ElIdInjectionContext = {
prefix: number
current: number
}
const defaultIdInjection = {
prefix: Math.floor(Math.random() * 10000),
current: 0,
}
export const ID_INJECTION_KEY: InjectionKey<ElIdInjectionContext> =
Symbol('elIdInjection')
export const useIdInjection = (): ElIdInjectionContext => {
return getCurrentInstance()
? inject(ID_INJECTION_KEY, defaultIdInjection)
: defaultIdInjection
}
export const useId = (deterministicId?: MaybeRef<string>): Ref<string> => {
const idInjection = useIdInjection()
if (!isClient && idInjection === defaultIdInjection) {
debugWarn(
'IdInjection',
`Looks like you are using server rendering, you must provide a id provider to ensure the hydration process to be succeed
usage: app.provide(ID_INJECTION_KEY, {
prefix: number,
current: number,
})`
)
}
const namespace = useGetDerivedNamespace()
const idRef = computed(
() =>
unref(deterministicId) ||
`${namespace.value}-id-${idInjection.prefix}-${idInjection.current++}`
)
return idRef
}