Template refs и nextTick
↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая
Зачем это на собесе
Доступ к DOM и «почему DOM ещё не обновился» — типичные вопросы.
Объяснение
Template ref — ссылка на DOM-элемент или экземпляр компонента.
<script setup lang="ts">
import { ref, useTemplateRef, onMounted, nextTick } from "vue";
const input = useTemplateRef<HTMLInputElement>("nameInput"); // 3.5+ (или ref<HTMLInputElement | null>(null) с тем же именем)
const list = ref<HTMLElement | null>(null);
const rows = useTemplateRef<HTMLElement[]>("rows"); // в v-for — массив
onMounted(() => input.value?.focus());
async function add() {
items.value.push(newItem());
await nextTick(); // ждём обновления DOM
list.value?.lastElementChild?.scrollIntoView();
}
</script>
<template>
<input ref="nameInput" />
<ul ref="list"><li v-for="i in items" :key="i.id" ref="rows">{{ i.title }}</li></ul>
<ChildForm ref="form" /> <!-- экземпляр компонента: доступен только defineExpose -->
</template>nextTick: Vue применяет изменения DOM асинхронно и пакетно (одна отрисовка за тик). После изменения состояния DOM ещё не обновлён; await nextTick() (или nextTick(cb)) выполняется после обновления.
count.value++;
console.log(el.value.textContent); // старое
await nextTick();
console.log(el.value.textContent); // новоеФункции-ref: :ref="(el) => setRef(el, id)" — для динамических случаев.
Использования: фокус, измерение размеров, прокрутка, инициализация библиотек с DOM, вызов методов дочернего компонента (form.value?.validate()).
Нюансы и подводные камни
- Ref пуст (
null) до монтирования и приv-iffalse. - Порядок элементов в массиве refs в
v-forне гарантирован. - Для доступа к дочернему компоненту нужен
defineExpose. - Злоупотребление refs вместо данных/событий делает код императивным.
- Изменение состояния и чтение DOM в одном тике даёт устаревшие значения.
Практика
- Фокусируйте поле после появления через
nextTick. - Прокрутите список к добавленному элементу.
- Вызовите
validate()дочерней формы через ref.
Вопросы с ответами
Зачем
nextTick?Дождаться применения отложенных обновлений DOM после изменения состояния.
Когда template ref доступен?
После монтирования (
onMounted) и пока элемент существует.