Template Refs
Get a direct reference to a DOM element or a child component instance using template refs.
On this page 7 sections
Why You Sometimes Need Direct DOM Access
Vue's declarative model handles the vast majority of UI needs without touching the DOM directly. But some things — focusing an input, reading an element's measured size, integrating a non-Vue library — genuinely require a direct reference to the actual DOM node.
Creating a Template Ref
Add a ref attribute to an element in the template, and declare a matching ref() in <script setup> with the exact same name — Vue automatically connects the two after the component mounts.
<script setup>import { ref, onMounted } from 'vue';
const inputEl = ref(null); // must match the template\'s ref="inputEl"
onMounted(() => { inputEl.value.focus(); // inputEl.value is the actual <input> DOM element});</script>
<template> <input ref="inputEl" /></template>A template ref is null until the component has mounted — always access it inside onMounted or a later lifecycle hook/event handler, never during the component's initial setup.
Refs on Components
Placing a ref on a custom component gives you its exposed instance — but only whatever that child explicitly exposed with defineExpose, covered in the <script setup> lesson.
<script setup>import { ref } from 'vue';import CustomInput from './CustomInput.vue';
const customInputRef = ref(null);
function focusChild() { customInputRef.value.focus(); // works only if CustomInput exposed \'focus\'}</script>
<template> <CustomInput ref="customInputRef" /></template>Refs Inside v-for
A ref attribute inside a v-for loop collects into an array rather than a single element, in the same order as the source array.
<script setup>import { ref } from 'vue';
const itemRefs = ref([]);const items = ['A', 'B', 'C'];</script>
<template> <li v-for="item in items" :key="item" ref="itemRefs">{{ item }}</li></template>Common Beginner Mistakes
This bypasses Vue's reactivity model — reserve template refs for genuine DOM-level needs (focus, measurement, third-party library integration), not everyday data flow.
The names must match exactly for Vue to connect them — a mismatch silently leaves the ref's value as null.
FAQs
Yes — bind it with :ref="dynamicName" instead of a static string, useful for programmatically generated lists of refs.
They share the ref() function and .value access pattern, but a template ref specifically holds a DOM element or component instance rather than arbitrary reactive data.
Summary
Template refs are your escape hatch for genuine, direct DOM access, connected automatically once a component mounts. Next, you'll learn to build your own reusable DOM behavior with custom directives.