Ref na prvek

Prvky stránky za vás vytváří Vue, a tak je sami potřebujete jen zřídka. Některé věci se ale dají udělat jen s prvkem: dát kurzor do textového pole pomocí focus(), posunout stránku k němu, spustit video. K tomu potřebujete samotný prvek, jak vám ho v kurzu JavaScriptu dávalo querySelector().

Ve Vue prvek v šabloně označíte atributem ref s názvem podle vaší volby a ve skriptu ho získáte pomocí useTemplateRef() se stejným názvem:

<script setup>
import { onMounted, useTemplateRef } from "vue";

const vzkaz = useTemplateRef("vzkaz");

onMounted(() => {
    vzkaz.value.focus();
});
</script>

<template>
    <label>
        Vzkaz pro baristu
        <textarea ref="vzkaz"></textarea>
    </label>
</template>

vzkaz je ref na prvek (anglicky template ref): ref, jehož .value je prvek, tady samotná textarea, se vším, co znáte z DOM: focus(), value, classList… Když se aplikace spustí, kurzor je v textovém poli a zákazník může hned psát. (V tomto cvičení tam po kliknutí na Spustit skočí i váš kurzor: do editoru se vrátíte kliknutím.)

Kdy ho můžete použít? Až když je komponenta připojená. Předtím prvek ještě neexistuje a vzkaz.value je null. Proto je focus() v onMounted. V obsluze události, třeba kliknutí, prvek existuje taky: na tlačítko se dá kliknout, až když je na stránce.

Proč ne document.querySelector("textarea")? To hledá v celé stránce a najde první textarea, která může patřit jiné komponentě. Ref na prvek je vždycky prvek ze šablony právě této komponenty.

useTemplateRef() je ve Vue nové od verze 3.5. Ve starším kódu uvidíte const vzkaz = ref(null); spolu s ref="vzkaz", tedy se stejným názvem, jaký má proměnná, a funguje to stejně.

Typická chyba: různé názvy. S ref="vzkaz" v šabloně a useTemplateRef("vzkazy") ve skriptu zůstane vzkaz.value pořád null a vzkaz.value.focus() skončí chybou TypeError: Cannot read properties of null (reading 'focus').

Pokyny

  1. Když se aplikace spustí, dejte kurzor do textového pole pro hledání: dejte mu ref="hledani", získejte ho pomocí useTemplateRef("hledani") a v onMounted zavolejte jeho focus().

  2. Za textové pole přidejte tlačítko Vymazat, které vyhledávání vyprázdní a dá kurzor zpátky do textového pole, aby zákazník mohl hned hledat něco jiného.