useTemplateRef.ts 1.0 KB

1234567891011121314151617181920212223242526272829303132333435
  1. import { type ShallowRef, readonly, shallowRef } from '@vue/reactivity'
  2. import { getCurrentInstance } from '../component'
  3. import { warn } from '../warning'
  4. import { EMPTY_OBJ } from '@vue/shared'
  5. export function useTemplateRef<T = unknown, Keys extends string = string>(
  6. key: Keys,
  7. ): Readonly<ShallowRef<T | null>> {
  8. const i = getCurrentInstance()
  9. const r = shallowRef(null)
  10. if (i) {
  11. const refs = i.refs === EMPTY_OBJ ? (i.refs = {}) : i.refs
  12. let desc: PropertyDescriptor | undefined
  13. if (
  14. __DEV__ &&
  15. (desc = Object.getOwnPropertyDescriptor(refs, key)) &&
  16. !desc.configurable
  17. ) {
  18. warn(`useTemplateRef('${key}') already exists.`)
  19. } else {
  20. Object.defineProperty(refs, key, {
  21. enumerable: true,
  22. get: () => r.value,
  23. set: val => (r.value = val),
  24. })
  25. }
  26. } else if (__DEV__) {
  27. warn(
  28. `useTemplateRef() is called when there is no active component ` +
  29. `instance to be associated with.`,
  30. )
  31. }
  32. return (__DEV__ ? readonly(r) : r) as any
  33. }