Interpolacja, wiązanie danych i podstawowe zdarzenia

Po zapoznaniu się z dodaniem Vue i strukturą komponentu, przejdźmy do fundamentalnych mechanizmów Vue, czyli wiązania danych z widokiem (data binding) oraz obsługi zdarzeń. Vue wyróżnia się reaktywnością – zmiany danych automatycznie wpływają na zawartość HTML, dzięki czemu pisanie interaktywnego interfejsu jest znacznie uproszczone. Omówimy teraz podstawy: interpolację w tekście, wiązanie atrybutów oraz obsługę zdarzeń w Vue 3.

Interpolacja danych w HTML

Interpolacja to najprostszy sposób wyświetlania dynamicznych danych w szablonie Vue. Wykorzystuje ona tzw. składnię „wąsów” – podwójnych nawiasów klamrowych {{ }}. Umieszczając wyrażenie lub nazwę właściwości wewnątrz {{ }} w kodzie HTML, instruujemy Vue, aby w to miejsce wstawił bieżącą wartość danej właściwości. Przykład interpolacji:

<p>Wiadomość: {{ msg }}</p>

Jeśli nasz komponent posiada właściwość msg w swoim stanie (np. w data() zwracamy { msg: 'Hello' }), to w przeglądarce zobaczymy zawartość tej właściwości w miejscu klamer. Vue automatycznie zadba o aktualizację wyświetlanej wartości za każdym razem, gdy zmieni się msg. Interpolacja działa tylko w treści HTML między tagami. Nie można używać {{ }} bezpośrednio w atrybutach HTML (np. <img src="{{ dynamicUrl }}"> jest niepoprawne) – do tego służą dedykowane dyrektywy omówione poniżej.

Warto wspomnieć, że interpolacja tekstu renderuje dane jako zwykły tekst. Gdy chcemy wstrzyknąć surowy kod HTML przechowywany w zmiennej, Vue oferuje dyrektywę v-html, jednak korzystanie z niej niesie ryzyko XSS i powinno być ograniczone tylko do zaufanych treści. W większości przypadków standardowa interpolacja {{ }} jest wystarczająca i bezpieczna.

Wiązanie atrybutów z użyciem v-bind

Aby dynamicznie zmieniać atrybuty elementów HTML w reakcji na zmiany danych, Vue udostępnia dyrektywę v-bind. Pozwala ona powiązać (zbindować) wartości właściwości ze wskazanym atrybutem HTML. Składnia pełna to v-bind:nazwaAtrybutu="wyrażenie" – np. v-bind:href="url" ustawi atrybut href linku na wartość właściwości url z naszych danych. Dzięki v-bind framework synchronizuje atrybut elementu z wartością zmiennej – jeśli zmienna się zmieni, atrybut automatycznie zostanie zaktualizowany.

Ponieważ używanie v-bind jest bardzo częste, Vue oferuje skróconą składnię: zamiast pisać v-bind: można użyć dwukropka : przed nazwą atrybutu. Przykładowo, zapis <img :src="obrazekUrl"> jest równoważny z <img v-bind:src="obrazekUrl">. Tak samo <div :id="dynamicId"> to skrót od <div v-bind:id="dynamicId">. Używanie skrótu : czyni kod bardziej zwięzłym i czytelnym, dlatego jest on powszechnie stosowany.

Przykład zastosowania v-bind w praktyce (wraz z interpolacją dla porównania):

<div id="app">  <h2>{{ tytul }}</h2>  <img :src="obrazekUrl" alt="Opis obrazka" /> </div> <script>  const { createApp } = Vue;  createApp({    data() {      return {        tytul: 'Mój pierwszy obrazek w Vue',        obrazekUrl: 'https://placekitten.com/300/200' // przykładowy URL obrazka      };    }  }).mount('#app'); </script>

W powyższym fragmencie tytuł obrazka jest wstawiany w nagłówku <h2> poprzez interpolację {{ tytul }}, natomiast adres obrazka jest dowiązany do atrybutu src tagu <img> za pomocą :src. Gdyby zmienna obrazekUrl została zmieniona (np. wskazywała na inny link), Vue automatycznie zaktualizuje atrybut src obrazka na stronie, bez potrzeby ręcznego manipulowania DOM.

Obsługa zdarzeń za pomocą v-on

Interaktywność aplikacji wymaga reagowania na działania użytkownika, takie jak kliknięcia, wprowadzanie tekstu czy przesuwanie myszy. W Vue do obsługi zdarzeń służy dyrektywa v-on, pozwalająca nasłuchiwać na zdarzenia DOM i wywoływać w odpowiedzi określone metody lub wyrażenia. Pełna składnia to v-on:nazwaZdarzenia="funkcjaLubKod" – np. v-on:click="wywolajCos" sprawi, że po kliknięciu w element zostanie wykonana metoda wywolajCos naszego komponentu.

Podobnie jak w przypadku v-bind, dla v-on istnieje skrócona składnia: można zastąpić v-on: znakiem @. Dlatego zamiast v-on:click zazwyczaj piszemy po prostu @click. Przykładowy kod z użyciem v-on i skrótu @:

 <button v-on:click="powitaj">Kliknij mnie (v-on)</button> <!-- To samo z użyciem skrótu '@': --> <button @click="powitaj">Kliknij mnie (@click)</button>

W obu przypadkach kliknięcie przycisku spowoduje wywołanie metody powitaj zdefiniowanej w naszym komponencie (tak jak w poprzedniej sekcji przykładu z powitaj() w data/methods). Argumentem dyrektywy v-on jest nazwa zdarzenia DOM, którego obsługę chcemy podpiąć – np. click, input, submit itp. Vue automatycznie przekazuje kontekst komponentu, więc wewnątrz metody możemy odwoływać się do this (w Options API) lub korzystać ze zmiennych z setup() (w Composition API).

Przykład typowego zastosowania – licznik (counter): Połączmy teraz interpolację, bindowanie i obsługę zdarzeń, tworząc prosty licznik. Będzie on miał przycisk zwiększający wartość licznika i tekst wyświetlający bieżący stan. Dodatkowo pokażemy dynamiczne wiązanie atrybutu disabled przycisku oraz użycie atrybutu title do wyświetlenia podpowiedzi po najechaniu kursorem:

<div id="app">  <h3>Licznik: {{ count }}</h3>  <button @click="increment" :disabled="count >= max">    Dodaj +1  </button>  <p :title="'Aktualny stan: ' + count">    Najedź kursorem tutaj, aby zobaczyć stan licznika.  </p> </div> <script>  const { createApp } = Vue;  createApp({    data() {      return {        count: 0,    // bieżąca wartość licznika        max: 5       // maksymalna wartość licznika      };    },    methods: {      increment() {        if (this.count < this.max) {          this.count++;        }      }    }  }).mount('#app');
 </script>

Omówienie działania powyższego przykładu: W nagłówku <h3> używamy interpolacji {{ count }}, aby wyświetlić aktualną wartość licznika. Przycisk Dodaj +1 ma zdefiniowany nasłuch na zdarzenie kliknięcia @click="increment", który wywołuje metodę increment() komponentu. Metoda increment zwiększa wartość count o jeden, ale tylko jeśli nie został osiągnięty maksimum (prosta logika zabezpieczająca, aby pokazać wykorzystanie danych w metodzie). W atrybucie disabled przycisku wykorzystujemy v-bind (skróconą składnię :) z warunkiem count >= max. Gdy wartość count osiągnie wartość max (5), wyrażenie to zwróci true, co spowoduje przypisanie atrybutu disabled do elementu <button> (przycisk stanie się nieaktywny). Gdy count jest mniejsze niż max, wyrażenie count >= max jest false i atrybut disabled nie będzie obecny, dzięki czemu przycisk jest aktywny (Vue usuwa atrybut dla wartości falsy). Natomiast <p> poniżej ma atrybut title dowiązany do tekstu "Aktualny stan: " + count. Dzięki temu po najechaniu kursorem na ten akapit przeglądarka pokaże dymek z aktualną wartością licznika. Ten atrybut title aktualizuje się automatycznie wraz ze zmianą count, ponieważ jest powiązany poprzez reakcję Vue.

Powyższy przykład ilustruje kluczowe koncepty: interpolacja ({{ count }}), wiązanie atrybutu (:disabled, :title) oraz obsługa zdarzenia (@click). Widzimy, że dzięki reaktywności Vue nie musimy bezpośrednio manipulować DOM (np. używać document.querySelector czy ręcznie dodawać atrybutów) – wystarczy zdefiniować powiązania, a framework sam zadba o aktualizację widoku, gdy zmienią się dane. To znacząco upraszcza tworzenie interaktywnych aplikacji.