Шаблонные ссылки: ref на элемент
Иногда нужен прямой доступ к настоящему DOM-элементу — фокус на поле, измерение размеров, работа с canvas. Разбираем механизм шаблонных ссылок.
Template ref (шаблонная ссылка) — способ получить ссылку на реальный DOM-элемент из кода компонента, не прибегая к
document.querySelector.
Когда это нужно
Vue сам управляет DOM, и руками туда лезть обычно не надо. Но есть исключения: поставить фокус в поле ввода, прокрутить к элементу, измерить его ширину, отдать canvas сторонней библиотеке графиков. Для этого и нужны template refs.
Как устроена шаблонная ссылка
Механизм из двух частей: атрибут ref="имя" на элементе в шаблоне и одноимённая ref-переменная в скрипте. Vue свяжет их, когда элемент окажется в DOM:
<template>
<input ref="inputEl" placeholder="Я получу фокус">
</template>
<script setup>
import { ref, onMounted } from 'vue'
const inputEl = ref(null) // имя совпадает с ref в шаблоне
onMounted(() => {
inputEl.value.focus() // ставим фокус в поле
})
</script>
Главное правило: только после монтирования
До монтирования настоящего элемента ещё нет, поэтому inputEl.value равен null. Обращаться к нему можно только в onMounted или позже — например, по клику. Попытка достучаться раньше даст ошибку «cannot read property of null». Промоделируем этот жизненный путь:
// Имитация: элемент появляется только в onMounted
let elementRef = { value: null };
function tryFocus(label) {
if (elementRef.value === null) {
console.log(`${label}: элемента ещё нет (null)`);
} else {
console.log(`${label}: фокус на «${elementRef.value}»`);
}
}
tryFocus("До mounted");
elementRef.value = "input#name"; // onMounted: Vue связал ссылку
tryFocus("После mounted");
Вывод:
До mounted: элемента ещё нет (null) После mounted: фокус на «input#name»
Не злоупотребляйте
Template refs — «аварийный люк» в императивный мир. Если вы тянетесь к нему, чтобы поменять текст или видимость элемента — остановитесь: это задача реактивности ({{ }}, v-if). Шаблонные ссылки нужны только для того, что декларативно не выразить: фокус, прокрутка, измерения, интеграция со сторонним кодом.
| Задача | Правильный инструмент |
| Поменять текст элемента | интерполяция {{ }} |
| Показать/скрыть | v-if / v-show |
| Поставить фокус, измерить, прокрутить | template ref |
Итог
- Template ref даёт прямой доступ к DOM-элементу без
querySelector. - Атрибут
ref="имя"в шаблоне + одноимённаяref-переменная в скрипте. - Элемент доступен только начиная с
onMounted; раньше.valueравенnull. - Используйте лишь для фокуса, измерений, прокрутки и интеграций — не для текста и видимости.