Kolejna prosta lekcja, poznajemy czym jest template w Vue.js. Do dzieła.

Ok, markup prostego licznika:

<div id="app">
        <p>Counter {{counter}}</p>
        <button @click="increment(1)">+1</button>
        <button @click="increment(-1)">-1</button>
</div>

Prosty licznik od strony JS:

const app = Vue.createApp({
    data(){
        return {
            counter: 0
        };
    },

    methods: {
        increment(by){
           this.counter += by;
        }
    },
    
  });
  
app.mount('#app');

Jak robiliśmy unmount, to cała zawartość #app nam znikała. Bo tam pod spodem jest tag template. I nawet możemy wywalić całą zawartość markupu #app i przenieść do template:

const app = Vue.createApp({
    data(){
        return {
            counter: 0
        };
    },

    methods: {
        increment(by){
           this.counter += by;
        }
    },

    template: `<p>Counter {{counter}}</p>
        <button @click="increment(1)">+1</button>
        <button @click="increment(-1)">-1</button>`
    
  });
  
app.mount('#app');

Wszystko działa tak samo, choć nasze #app wygląda teraz tak:

<div id="app">
</div>

Tak też będzie wyglądać, jeżeli wykonamy unmount. Czy są zalety takiego podejścia? Cóż…

const app = Vue.createApp({
    data(){
        return {
            counter: 0
        };
    },

    methods: {
        increment(by){
           this.counter += by;
        }
    },

    template: `<p>Counter {{counter}}</p>
        <button @click="increment(1)">+1</button>
        <button @click="increment(-1)">-1</button>`,
    
    beforeMount() {
        alert("I will be mounted in a minute");
    },
    
  });
  
app.mount('#app');

Teraz przed mountem nie zobaczymy żadnego markupu, nic nam brzydko nie mignie, nawet alert, który wymusza pauzę (dobry do prostego debugowania, robi stop na render wszystkiego) nie będzie mieć z tyłu nieprzeparsowanego markupu.

Ale to nie jest powód, dla którego template jest obecne w Vue.js. Powodem są komponenty, apka nawet powinna mieć markup, oddzieloną logikę markupową od logiki programistycznej.

Powód to komponenty:

const app = Vue.createApp({
   

});

app.component('person-component', {
    props: ['name'],
    template: `<li>Name: {{name}}</li>`
});

app.mount('#app');

Uwaga – nazwa komponentu to dwa wyrazy, jak przerabialiśmy web components (kurs JS) to wiemy dlaczego. Teraz możemy używać tych komponentów:

<div id="app">
        <ul>
            <person-component name="John"></person-component>
            <person-component name="Jane"></person-component>
        </ul>
    </div>

Możemy też utworzyć tablicę z osobami:

const app = Vue.createApp({
    data(){
        return {
            people: [
                {
                    id: 1,
                    name: "John"
                },
                {
                    id: 2,
                    name: "Jane"
                }
            ]
        }
    }
});

app.component('person-component', {
    props: ['name'],
    template: `<li>Name: {{name}}</li>`
});

app.mount('#app');

Teraz możemy dynamicznie w pętli wyświetlać nasze osoby, musimy tylko pamiętać, że skoro dynamicznie, to :name, nie name:

 <div id="app">
        <ul>
            <person-component 
            v-for="person in people" 
            :key="person.id" 
            :name="person.name"></person-component>
        </ul>
</div>