Vue mette a disposizione una serie di direttive predefinite grazie alle quali siamo in grado di controllare quali elementi devono essere mostrati o rimossi/nascosti al verificarsi di una determinata condizione. Le direttive che incontreremo sono v-if
, v-else
, v-else-if
ed infine v-show
. Vedremo in cosa differiscono v-if
e v-show
che forniscono due approcci diversi alla risoluzione dello stesso problema.
La direttiva v-if
Partiamo subito dalla direttiva v-if
che aggiunge o rimuove uno o più elementi dal DOM a seconda che l’espressione passata come valore sia equiparabile al valore true o false.
Supponiamo di aver creato una nuova istanza Vue come mostrato nel frammento di codice sottostante.
const vm = new Vue({
el: "#root",
data: {
show: false
},
methods: {
toggleP(event) {
this.show = !this.show;
}
}
});
E creiamo all’interno di un file HTML un elemento <button>
ed un elemento <p>
. Con l’aiuto della direttiva v-on (@) gestiamo eventuali click sul pulsante invocando il metodo toggleP()
che si limita ad invertire il valore booleano della proprietà vm.$data.show
. Facciamo inoltre uso della tecnica dell’interpolazione, combinata ad un operatore ternario, per chiarire quale operazione verrà effettuata alla pressione del pulsante.
<main id="root">
<button @click="toggleP">
{{ this.show ? 'Nascondi' : 'Mostra' }} Paragrafo
</button>
<p v-if="show">
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
magna, vel scelerisque nisl consectetur et. Duis mollis, est non commodo
luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.
</p>
</main>
A seconda del valore della proprietà vm.$data.show
, verrà inserito o rimosso il paragrafo dal DOM.
È bene porre l’accento su un aspetto importante del funzionamento della direttiva v-if
. Quando l’espressione passata a quest’ultima è falsa, l’elemento, su cui è applicata la direttiva, viene rimosso dal DOM e non semplicemente nascosto attraverso qualche regola CSS. Possiamo notare tale comportamento nelle due immagini sottostanti.
v-if e l’elmento <template>
Abbiamo visto come utilizzare la direttiva v-if per mostrare o nascondere un singolo elemento. Se però desideriamo ottenere lo stesso effetto su più elementi contemporaneamente, dovremo racchiuderli in un elemento base. La direttiva v-if si occuperà infatti di aggiungere o rimuovere l’elemento su cui è applicata e tutti i suoi discendenti.
<main id="root">
<button @click="toggleP">
{{ this.show ? 'Nascondi' : 'Mostra' }} Paragrafo
</button>
<div v-if="show">
<h1>Vulputate Condimentum Vehicula</h1>
<p>
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
magna, vel scelerisque nisl consectetur et. Duis mollis, est non commodo
luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.
</p>
</div>
</main>
Nell’esempio riportato sopra, sarà l’intero elemento <div>
(e quindi h1
e p
presenti al suo interno) ad essere inserito o rimosso dal DOM.
Se però volessimo controllare più elementi contemporaneamente senza volerli racchiudere in un elemento esterno, allora possiamo applicare la direttiva v-if
su un elemento di tipo <template>
. Quest’ultimo non sarà mai aggiunto al DOM, al contrario solo gli elementi in esso contenuti verranno inseriti o rimossi in base al valore dell’espressione assegnata alla direttiva v-if
.
<main id="root">
<h1>Vulputate Condimentum Vehicula</h1>
<button @click="toggleP">
{{ this.show ? 'Nascondi' : 'Mostra' }} Paragrafi
</button>
<template v-if="show">
<p>
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
magna, vel scelerisque nisl consectetur et. Duis mollis, est non
commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec
elit.
</p>
<p>
Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas
sed diam eget risus varius blandit sit amet non magna. Aenean eu leo
quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
Curabitur blandit tempus porttitor.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo
risus, porta ac consectetur ac, vestibulum at eros. Nulla vitae elit
libero, a pharetra augue. Curabitur blandit tempus porttitor. Aenean
eu leo quam. Pellentesque ornare sem lacinia quam venenatis
vestibulum.
</p>
</template>
</main>
Le direttive v-else e v-else-if
La direttiva v-else
va usata insieme a v-if
per mostrare degli elementi nel DOM quando l’espressione passata a v-if
è false. Al contrario se l’espressione della direttiva v-if
è true, l’elemento su cui è applicata v-else verrà sostituito da quello su cui è applicata v-if
.
<main id="root">
<button @click="toggleP">
Cambia visibilità paragrafi
</button>
<p v-if="show">
Visibile se la proprietà <code>vm.$data.show</code>
è uguale a <code>true</code>.
</p>
<p v-else>
Visibile se la proprietà <code>vm.$data.show</code>
è uguale a <code>false</code>.
</p>
</main>
La direttiva v-else
non riceve alcuna espressione e va applicata ad un elemento, anche di tipo <template>
, disposto immediatamente dopo un altro elemento su cui è stata applicata la direttiva v-if
o v-else-if
.
La direttiva v-else-if
riceve un’espressione e accompagna v-if
e v-else
nel caso si intenda mostrare un elemento testando più di una condizione.
Come è facile intuire dal nome, le tre direttive si comportano come le istruzioni condizionali di qualsiasi linguaggio di programmazione consentendo in questo caso di mostrare elementi diversi dopo aver testato una o più espressioni.
<main id="root">
<button @click="generateRandomValue">
Genera un numero casuale
</button>
<p v-if="randomNumber < 5">
Il numero generato è:
<span style="color: crimson">
minore di 5
</span>
</p>
<p v-else-if="randomNumber > 5">
Il numero generato è:
<span style="color: darkgreen">
maggiore di 5
</span>
</p>
<p v-else>
Il numero generato è:
<span style="color: goldenrod">
uguale a 5
</span>
</p>
</main>
const vm = new Vue({
el: "#root",
data: {
randomNumber: 0
},
methods: {
generateRandomValue(event) {
this.randomNumber = Math.round(Math.random() * 10);
}
}
});
Usare l’attributo key per evitare comportamenti indesiderati
L’esempio riportato sopra è stato volutamente realizzato in modo da evidenziare il comportamento delle tre direttive applicate contemporaneamente. Notiamo che Vue.js non rimuove o aggiunge gli elementi, ma provvede ad apportare solo le modifiche necessarie cercando di riutilizzare le parti che non hanno subito variazioni. In questo modo gli aggiornamenti avvengono in maniera rapida e migliorano considerevolmente le prestazioni del framework.
Questo comportamento da un lato consente di ottenere una maggiore efficienza e velocità nell’effettuare le modifiche, dall’altro può però provocare dei comportamenti non desiderati e inaspettati.
Consideriamo per esempio il frammento di codice riportato sotto in cui in base al valore della proprietà vm.$data.user
, mostriamo due diversi campi di accesso.
<main id="root">
<button
@click="selectUserType('privato')"
:disabled="userType === 'privato'"
>Utenti Privati</button>
<button
@click="selectUserType('azienda')"
:disabled="userType === 'azienda'"
>Aziende</button>
<div v-if="userType === 'privato'">
<label>E-mail</label>
<input placeholder="inserisci la tua email">
</div>
<div v-else>
<label>Codice Aziendale</label>
<input placeholder="inserisci il tuo codice identificativo">
</div>
</main>
const vm = new Vue({
el: "#root",
data: {
userType: 'privato'
},
methods: {
selectUserType(userType) {
this.userType = userType;
}
}
});
Se modifichiamo il valore della proprietà vm.$data.user
, Vue cerca di riutilizzare lo stesso campo di input e di aggiornare solo l’attributo placeholder
. Se però inseriamo dei caratteri nel campo di testo per gli utenti privati e clicchiamo sul pulsante per passare alla modalità ‘aziende’, ritroviamo i caratteri che avevamo precedentemente inserito.
Per evitare questo tipo di comportamento non desiderato possiamo indicare a Vue che si tratta effettivamente di due distinti campi di testo e che quindi non deve riutilizzare lo stesso elemento <input>
.
Per far ciò, basterà aggiungere sugli elementi <input>
un attributo key
con valore univoco.
<div v-if="userType === 'privato'">
<label>E-mail</label>
<input
placeholder="inserisci la tua email"
key="privato">
</div>
<div v-else>
<label>Codice Aziendale</label>
<input
placeholder="inserisci il tuo codice identificativo"
key="azienda">
</div>
v-show vs v-if
La direttiva v-show
, come v-if
, può essere usata per mostrare o nascondere un elemento (ed eventuali elementi discendenti) in base ad un’espressione passata come valore, ma non può essere accompagnata dalle direttive v-else-if
e v-else
.
Rispetto alla direttiva v-if
, v-show
usa la proprietà CSS display
per mostrare o nascondere un elemento.
Inoltre v-show
non può essere applicata sugli elementi di tipo <template>
.
Ripetiamo allora uno dei primi esempi visti in precedenza per la direttiva v-if
e riportiamo sotto il frammento di codice HTML in cui usiamo in questo caso la direttiva v-show
.
<main id="root">
<h1>Vulputate Condimentum Vehicula</h1>
<button @click="toggleP">
{{ this.show ? 'Nascondi' : 'Mostra' }} Paragrafo
</button>
<p v-show="show">
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
magna, vel scelerisque nisl consectetur et. Duis mollis, est non
commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec
elit.
</p>
</main>
Possiamo quindi notare la differenza con la direttiva v-if
nel video sottostante.
Riepilogo
In questa lezione abbiamo illustrato come usare le direttive v-if
, v-else
e v-else-if
per mostrare o rimuovere un elemento dal DOM in base ad una determinata condizione. Abbiamo infine evidenziato le differenze fra v-if
e v-show
ricordando che quest’ultima, al contrario della prima, si limita ad usare la proprietà CSS display
per nascondere un elemento se l’espressione, passata come valore, risulta essere false.