HTML elements Refs

In order to create a reference to an HTML element we use the ref attribute, where we set a reference name. We link the reference to a reactive state with the same name. For Vue 3.5+, we can use useTemplateRef() which is more type-safe.

We can also use an inline expression or method for assigning the element instance to any reactive state.

const input = ref(null)
onMounted(() => {
  input.value.focus()
})

const inputRef = useTemplateRef('input-ref')
onMounted(() => {
  inputRef .value.focus()
})

watchEffect(() => {
  if (input.value) {
    input.value.focus()
  } else {
    // not mounted yet, or the element was unmounted (e.g. by v-if)
  }
})

const myRef = ref(null)
const setMyRef = (el) => {
  myRef = el
}
<template>
  
  <input ref="input" />
  <input ref="input-ref" />

  <input :ref="(el) => { myref = el }" />
  <input :ref="setMyRef" />

</template>

Components Refs

To reference a component, we use the same approach applied to HTML elements. Once having the reference we have access to the instance of the component.

import Child from './Child.vue'

const child = ref(null)
onMounted(() => {
  // child.value will hold an instance of <Child />
})

const childRef = useTemplateRef('child')
onMounted(() => {
  // childRef.value will hold an instance of <Child />
})
<template>
  <Child ref="child" />
</template>

In <script setup> all component content is private by default, so, if you want to access to any child’s state or function, they need to be exposed.

<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

// Compiler macros, such as defineExpose, don't need to be imported
defineExpose({
  a,
  b
})
</script>

Refs in v-for

We can reference multiple elements at once. For this case we need to set the ref attribute to the element which will render the list of elements.

const list = ref([
  /* ... */
])

const items = ref([])
onMounted(() => console.log(items.value))

const itemRefs = useTemplateRef('items')
onMounted(() => console.log(itemRefs.value))
<template>
  <ul>
    <li v-for="item in list" ref="items">
      {{ item }}
    </li>
  </ul>
</template>

References