Skip to content

Instantly share code, notes, and snippets.

@iamsonnn
Last active January 9, 2024 04:29
Show Gist options
  • Save iamsonnn/dbf6d8407a0959f7dc66f6d24231799c to your computer and use it in GitHub Desktop.
Save iamsonnn/dbf6d8407a0959f7dc66f6d24231799c to your computer and use it in GitHub Desktop.
Simplize Vue's template refs, make it work with IDE suggestion & compiler

Purpose: Make Vue's template ref (https://vuejs.org/guide/essentials/template-refs.html) more typescript friendly, make IDE suggestion and compiler validator better

Create a file name useRefs.ts in your utils/helpers directory

import { reactive } from 'vue'

export const useRefs = <T extends object>() => {
  const refs = reactive<T>({} as T)
  const toRef = (refName: keyof T) => (el: any) => ((refs as T)[refName as keyof T] = el)

  return {
    refs,
    toRef,
  }
}

Example usage:

<template>
  <input :ref="toRef('input')" />
</template>

<script setup lang="ts">
import { onMounted } from 'vue'
import { useRefs } from '@common/utils/useRefs'

const { refs, toRef } = useRefs<{
  input: InstanceType<typeof HTMLInputElement>
}>()

onMounted(() => {
  refs.input.focus()
})
</script>

What you got:

  • No more IDE warning
  • IDE suggestion every code with template refs
  • Complier checker works with Vue's exposes
@varHarrie
Copy link

varHarrie commented Jan 9, 2024

Other version:

<template>
  <div :ref="divRef.bind"></div>
</template>

<script setup lang="ts">
function useMyRef<T>() {
  const state = reactive({
    value: undefined as T | undefined,
    bind: (el: any) => {
      state.value = el;
    },
  });

  return state;
}

const divRef = useMyRef<HTMLDivElement>();

onMounted(() => {
  console.log(divRef.value);
})
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment