Kontynuacja lekcji poprzedniej, przecieramy szlaki w Vue.js. Poznajemy cykl życia obiektu App – do dzieła.

Ok, zepsujmy sobie poprzedni przykład, dodając pewne lifecycle hooks:

const app = Vue.createApp({
    data() {
      return {
        name: "John Doe",
        age: 30,
        link: "https://www.google.com",
        raw: "<strong>Hello World!</stron>"
      };
    },

    beforeCreate() {
            alert('I will be created in a moment');
    },

    created() {
            console.log('I am created');
    }
    
  });
  
app.mount('#app');

Teraz alert zatrzyma nam egzekujcę kodu. Zobaczymy napis z metody beforeCreate, zaś w tle czysty markup, nawiasy klamrowe, nazwy zmiennych. Dopiero po kliknięciu ok instancja zostanie utworzona, markup zamieni się w kod.

Ok, dodajmy sobie zmienną counter w data a także kolejne hooki:

const app = Vue.createApp({
    data() {
      return {
        name: "John Doe",
        age: 30,
        link: "https://www.google.com",
        raw: "<strong>Hello World!</stron>",
        counter: 0
      };
    },

    beforeCreate() {
            alert('I will be created in a moment');
    },

    created() {
            console.log('I am created');
    },

    beforeMount() {
        console.log('beforeMount');
      },
      mounted() {
        console.log('mounted');
    },
    
  });
  
app.mount('#app');

Nazwy mówią same za siebie, co te hooki robią. Ok, dodamy eventy do naszego markupu:

<div id="app">
        <p>Hello {{name.toUpperCase()}}. You are {{age * 12}} months old!</p>
        <p>Visit <a :href="link">Google</a></p>
        <p v-html="raw"></p>
        <button @click="counter++">Add 1</button>
        <button @click="counter--">Sub 1</button>
        <p>Result: {{ counter }}</p>
</div>

Ktoś kiedyś powiedział „React jest fajny, gdy tworzysz countery i inne hello worldy, dopiero później zaczyna być zły”. Nie wiem, co ten ktoś myślał, chyba nigdy nie widział Vue/Alpine/Svelte (to ostatnie niestety wymaga kompilacji).

W zasadzie tyle w tych framewrokach potrzeba, aby zrobić counter, a później jest tylko lepiej. Co nie zmienia faktu, że React to kawał dobrej technologii, ale np. Laravelowcy i PHPowcy to chcą tylko odrobinę reaktywności na swojej stronie, niekoniecznie Reacta, może jeszcze z TS, albo Angulara.

Nieważne, my tu nie o eventach, ale Vue App Lifecycle hooks. Teraz możemy dodać beforeUpdate i updated:

const app = Vue.createApp({
    data() {
      return {
        name: "John Doe",
        age: 30,
        link: "https://www.google.com",
        raw: "<strong>Hello World!</stron>",
        counter: 0
      };
    },

    beforeCreate() {
            alert('I will be created in a moment');
    },

    created() {
            console.log('I am created');
    },

    beforeMount() {
        console.log('beforeMount');
      },
      mounted() {
        console.log('mounted');
    },
    beforeUpdate(){
        alert("paused... i will be updated")
    },
    updated() {
        console.log("Im updated");
    },
    
  });
  
app.mount('#app');

Jeżeli kogoś denerwuje sposób, w jaki tutaj wszystko przekazujemy do Vue.createApp, to mam dla niego dwie dobre wiadomości:

  • to, co tu robimy to jest najbardziej prostackie użycie Vue, aby oswoić się z markupem i podstawowymi funkcjonalnościami. Możemy to sobie porównać do używania Blade::render zamiast tworzenia własnych widoków w Laravelu i korzystania z view(’path’). Ten poziom łopatologii tu stosujemy
  • Vue posiada już composition API, to jest taki bajer, który sprawia, że komponenty piszemy w jednym miejscu, za to dzielimy na trzy części (nie muszą być wszystkie):
    • templatka, markup htmlowy
    • script, część JSowa
    • style, część stylowa

Także nie ma co się martwić, Vue jest bardziej przejrzyste niż React, zwłaszcza dla początkujących.

Ok, teraz za każdym razem, jak wciśniemy guzik skrypt nam się zatrzyma przed update. Znaczy – nasz hook działa jak należy.

Ok, pod app dodamy sobie teraz unmount i zobaczymy co się dzieje:

app.mount('#app');


setTimeout(function () {
    app.unmount();
  }, 3000);

Na unmount cały nasz root element znika. To root element znika, możemy dodać coś powyżej i sprawdzić:

<h1>Hello World</h1>
    <div id="app">
        <p>Hello {{name.toUpperCase()}}. You are {{age * 12}} months old!</p>
        <p>Visit <a :href="link">Google</a></p>
        <p v-html="raw"></p>
        <button @click="counter++">Add 1</button>
        <button @click="counter--">Sub 1</button>
        <p>Result: {{ counter }}</p>
    </div>

Hello World zostanie, root element (#app) jest wyczyszczony na unmount.

Z tym wiążą się dwa ostatnie hooki cyklu życia aplikacji Vue:

const app = Vue.createApp({
    data() {
      return {
        name: "John Doe",
        age: 30,
        link: "https://www.google.com",
        raw: "<strong>Hello World!</stron>",
        counter: 0
      };
    },

    beforeCreate() {
            alert('I will be created in a moment');
    },

    created() {
            console.log('I am created');
    },

    beforeMount() {
        console.log('beforeMount');
      },
      mounted() {
        console.log('mounted');
    },
    beforeUpdate(){
        alert("paused... i will be updated")
    },
    updated() {
        console.log("Im updated");
    },
    beforeUnmount() {
        alert("I will be unmounted in a second");
      },
    unmounted() {
        console.log('unmounted');
      },
    
  });
  
app.mount('#app');


setTimeout(function () {
    app.unmount();
  }, 3000);

Więcej Vue już niedługo! Dodam tylko, że możemy mieć wiele Appek mountowanych do różnych elementów, ale one nie będą w żaden sposób siebie świadome i nie jest to najlepsze rozwiązanie – od tego są komponenty, które również poznamy w swoim czasie.