Struktura komponentu Vue

Składnia komponentu w Vue 3: Podstawowym elementem każdej aplikacji Vue są komponenty. Komponentem może być zarówno główna instancja aplikacji (root component), jak i mniejsze, wielokrotnego użytku części interfejsu. W Vue 3 można definiować komponenty na dwa główne sposoby – za pomocą Options API (znanego z Vue 2) lub nowszego Composition API. Niezależnie od podejścia, komponent posiada swój szablon (template) oraz logikę (dane i metody) opisującą zachowanie. W przypadku używania Vue bez procesu budowania (np. przez CDN), zazwyczaj definicja komponentu odbywa się w kodzie JavaScript, a szablonem jest bezpośrednio kod HTML w miejscu montowania komponentu lub łańcuch znaków.

Typowy komponent z wykorzystaniem Options API definiujemy jako obiekt zawierający m.in.:

  • data – obiekt lub funkcja zwracająca obiekt przechowujący stan aplikacji (dane reaktywne komponentu).
  • methods – obiekt z metodami (funkcjami), które można wywoływać z poziomu szablonu (np. w obsłudze zdarzeń) lub z innych metod komponentu.

Przy tworzeniu instancji aplikacji (komponentu głównego) przez createApp, przekazujemy właśnie taki obiekt konfiguracyjny. Oprócz data i methods możemy tam zdefiniować m.in. computed (właściwości obliczane zależne od danych) czy watch (reakcje na zmiany danych), ale w prostej pierwszej aplikacji nie jest to konieczne. Poniżej pokazano strukturę głównego komponentu z użyciem Options API w jednym pliku HTML:

 <div id="app">
  <p>{{ message }}</p>
  <button v-on:click="powitaj">Kliknij mnie</button>
 </div>

 <script>
  const { createApp } = Vue;
  createApp({
    data() {
      return {
        message: 'Witaj, świecie Vue!'
      };
    },
    methods: {
      powitaj() {
        alert(this.message);
      }
    }
  }).mount('#app');
 </script>

W powyższym przykładzie komponentem głównym jest obiekt przekazany do createApp. Ma on właściwość data() zwracającą obiekt z danymi (message) oraz metodę powitaj(), która odwołuje się do danych poprzez this.message. Szablonem komponentu jest po prostu zawartość elementu <div id="app"> w momencie montowania – Vue przeanalizuje tę zawartość i znajdzie w niej wiązania ({{ message }}) oraz dyrektywy (np. v-on:click) do powiązania z danymi i metodami komponentu.

Composition API vs Options API (krótko): Vue 3 wprowadziło Composition API jako alternatywę dla Options API, aby lepiej organizować logikę w komponentach, zwłaszcza gdy stają się one duże. Główna różnica polega na tym, że w Composition API zamiast definiować oddzielne pola obiektu (data, methods, itd.), używamy funkcji setup(), w której za pomocą importowanych funkcji Vue (np. ref, reactive, composables) tworzymy i konfigurujemy stan oraz działania komponentu. Zamiast korzystać z this, od razu operujemy na zmiennych i funkcjach wewnątrz setup(), a na końcu zwracamy obiekt zawierający elementy, które mają być dostępne w szablonie.

Z perspektywy początkującego Options API jest na ogół prostsze i bardziej intuicyjne, ponieważ grupuje logikę według przeznaczenia (dane, metody, itp.) i przypomina tradycyjne podejście z Vue 2medium.com. Natomiast Composition API oferuje większą elastyczność – pozwala grupować kod według funkcjonalności, lepiej współdzielić logikę pomiędzy komponentami (przez tzw. composable funkcje) oraz zapewnia lepsze wsparcie dla TypeScriptmedium.com. W praktyce Options API bywa łatwiejsze na start, ale Composition API ułatwia utrzymanie większych projektów. Dla przykładu, poniżej zobrazowano te dwa podejścia definiowania tego samego prostego komponentu:

 // Przykład: komponent z polem tekstowym i przyciskiem – Options API
 const KomponentOptions = {
  data() {
    return { msg: 'Tekst' };
  },
  methods: {
    zmienTekst() {
      this.msg = 'Zmieniony!';
    }
  }
 };

 // Przykład: ten sam komponent – Composition API
 const KomponentComposition = {
  setup() {
    const msg = Vue.ref('Tekst');
    function zmienTekst() {
      msg.value = 'Zmieniony!';
    }
    return { msg, zmienTekst };
  }
 };

Oba powyższe komponenty osiągają ten sam efekt – przechowują tekst msg i oferują metodę do jego zmiany. Różnica polega na składni: Options API korzysta z oddzielnych pól obiektu (data, methods) i odwołuje się do stanu przez this, podczas gdy Composition API wszystko definiuje wewnątrz setup() korzystając z funkcji reaktywnych (tu ref) i zmiennej msg bez potrzeby używania this. Dla początkujących rekomenduje się rozpoczęcie nauki od Options API, aby dobrze zrozumieć reaktywność i podstawy Vue, a następnie zapoznanie się z Composition API, gdy zajdzie potrzeba lepszej organizacji kodu.

Tworzenie komponentu głównego w jednym pliku HTML: Jak pokazano wcześniej, możliwe jest zdefiniowanie całej logiki aplikacji Vue w obrębie jednego pliku HTML (bez korzystania z plików .vue). Komponent główny (root) może być zdefiniowany „inline” w skrypcie osadzonym na stronie. W tym podejściu szablonem jest albo istniejący kod HTML wewnątrz elementu montowanego (jak <div id="app">), albo możemy jawnie określić opcję template w definicji komponentu jako łańcuch zawierający kod HTML. Na przykład, zamiast polegać na zawartości elementu HTML, moglibyśmy napisać:

 createApp({
  data() { return { komunikat: 'Cześć!' } },
  template: `<p>{{ komunikat }}</p>`
 }).mount('#app');

W powyższym kodzie przypisaliśmy szablon komponentu wprost w kodzie JavaScript za pomocą parametru template. Taka metoda bywa używana w prostych przykładach lub podczas szybkiego prototypowania. Należy jednak pamiętać, że przy bardziej złożonych szablonach wygodniej jest korzystać z naturalnego HTML w dokumencie albo (docelowo) przenieść komponenty do osobnych plików .vue i użyć narzędzi kompilujących. Mimo ograniczeń, umieszczenie komponentu głównego w jednym pliku HTML jest możliwe i bywa wystarczające na etapie nauki.