Рефы шаблона
Элементы страницы создаёт за вас Vue, поэтому они редко нужны вам самим. Но кое-что можно сделать только с самим элементом: поставить курсор в текстовое поле через focus(), прокрутить страницу к нему, запустить видео. Для этого нужен сам элемент — как его давал вам querySelector() в курсе по JavaScript.
В Vue вы помечаете элемент в шаблоне атрибутом ref с любым именем, а в скрипте получаете его через useTemplateRef() с тем же именем:
<script setup>
import { onMounted, useTemplateRef } from "vue";
const note = useTemplateRef("note");
onMounted(() => {
note.value.focus();
});
</script>
<template>
<label>
Заметка для бариста
<textarea ref="note"></textarea>
</label>
</template>note — это реф шаблона: реф, у которого .value — элемент, здесь сам textarea, со всем, что вы знаете по DOM: focus(), value, classList… Когда приложение запускается, курсор оказывается в поле, и посетитель может сразу печатать. (В этом упражнении туда же уходит и ваш курсор, когда вы нажимаете «Запустить»: щёлкните в редакторе, чтобы продолжить писать код.)
Когда его можно использовать? Только после того, как компонент смонтирован. До этого элемента ещё нет, и note.value равно null. Поэтому focus() стоит в onMounted. В обработчике события, например щелчка, элемент тоже уже есть: на кнопку можно нажать, только когда она на странице.
Почему не document.querySelector("textarea")? Он ищет по всей странице и находит первый textarea, который может принадлежать другому компоненту. Реф шаблона — всегда элемент шаблона самого этого компонента.
useTemplateRef() появился в Vue 3.5. В более старом коде вы увидите const note = ref(null); вместе с ref="note" — именем, совпадающим с именем переменной; это работает так же.
Типичная ошибка: разные имена. Если в шаблоне ref="note", а в скрипте useTemplateRef("notes"), то note.value остаётся null, и note.value.focus() завершается ошибкой TypeError: Cannot read properties of null (reading 'focus').
Задание
- 1
При запуске приложения поставьте курсор в поле поиска: задайте полю
ref="search", получите его черезuseTemplateRef("search")и вызовите егоfocus()вonMounted. - 2
После поля добавьте кнопку
Очистить, которая очищает поиск и возвращает курсор в поле, чтобы посетитель мог сразу ввести что-то другое.