back to top

Vue.js: Interpolazione e Data binding

Nella precedente lezione abbiamo creato il nostro primo esempio in Vue.js. Si tratta di una banale applicazione in cui abbiamo però adottato una delle forme più semplici di associazione tra i dati presenti nell’istanza Vue base e la porzione di codice HTML (data binding), ovvero l’interpolazione.

Interpolazione in Vue.js

L’interpolazione è una tecnica di aggiornamento delle informazioni unidirezionale. Ogni volta che una delle proprietà dell’oggetto data dell’istanza Vue base viene aggiornata, in automatico il framework provvede ad effettuare le opportune elaborazioni e riflettere i cambiamenti all’interno del template HTML.

La sintassi dell’interpolazione prevede l’uso di una doppia coppia di parentesi graffe all’interno delle quali è presente un’espressione ({{ expression }}). Ci si riferisce a questo tipo di sintassi con il termine Mustache syntax visto che le parentesi graffe ricordano la forma dei baffi. Vue provvede a sostituire le parentesi graffe con il valore dell’espressione elaborata.

<h1>Name: {{ person.name }}</h1>

All’interno delle parentesi graffe, oltre alle singole proprietà, possiamo inserire una vera e propria espressione javascript come le seguenti:

{{ person.name + ' ' + person.surname }}

{{ new Date() }}

{{ value * 2 + 1 }}

{{ person.name.toUpperCase() }}

Le parentesi graffe devono però contenere una singola espressione e non è possibile usare blocchi per il controllo di flusso o cicli. In caso di necessità possiamo però ricorrere all’operatore ternario (anche operatori ternari annidati e disposti su più righe come mostrato sotto).

{{ 
      noOfProducts > 1 ? 
      noOfProducts + ' prodotti ancora disponibili' : 
      noOfProducts === 1 ?
      'Ultimo prodotto disponibile' :
      'Nessun prodotto disponibile' 
}}

La direttiva v-once

Vue mette a disposizione anche la direttiva v-once che permette di eseguire l’interpolazione una volta sola e non aggiornare le informazioni in caso di modifica dei dati. Come per le altre direttive che incontreremo nel resto di questa guida, v-once si applica ad un elemento HTML come se fosse un attributo. Si tratta di una tecnica usata da Vue (e da altri framework come Angular) per estendere le funzionalità degli elementi. Le direttive sono infatti speciali attributi il cui nome è contraddistinto dal prefisso ‘v-‘. Fatta eccezione per la direttiva v-for che incontreremo nelle prossime lezioni, a ciascuna direttiva può essere assegnato un valore purché sia una singola espressione Javascript.

Riprendendo l’esempio della lezione precedente, possiamo applicare la direttiva v-once al paragrafo presente nel file index.html. Così facendo, se proviamo nuovamente a modificare vm.$data.name dalla console degli strumenti per sviluppatori del browser, le informazioni mostrate nella pagina non subiranno alcun aggiornamento.

<div id="app">
  <!-- Applichiamo la direttiva v-once al paragrafo -->
  <p v-once>Hello, {{ name }}</p>
</div>
https://vimeo.com/461584646

La direttiva v-html

La sintassi vista finora interpreta i dati come semplici stringhe di testo. Per inserire in una pagina del codice HTML dovremo usare un’altra direttiva, ovvero v-html. Possiamo notare la differenza fra i due approcci, nell’esempio sottostante.

<div id="app">
  <div>{{ html }}</div>
  <div v-html="html"></div>
</div>
const vm = new Vue({
  el: '#app',
  data: {
    html: `
      <p style="color: mediumturquoise; font-size: 2em;" class="my-class">
        codice html
      </p>
    `
  }
});
Pagina web che fa uso della direttiva v-html

La direttiva v-cloak

Abbiamo visto alcuni esempi che fanno uso del meccanismo dell’interpolazione o di direttive come v-once e v-html. Uno dei problemi che può sorgere è rappresentato dalla possibilità che venga mostrato il template non compilato e di conseguenza la sintassi che fa uso delle parentesi graffe fin quando l’istanza base Vue non ha completato il processo di inizializzazione. Ciò è particolarmente visibile su una connessione lenta.

Se apriamo il pannello Network degli strumenti per sviluppatori del browser possiamo dunque simulare una simile condizione impostando l’opzione Network Throttling sul valore Slow 3G.

impostazioni network throttling degli strumenti per sviluppatori del browser

Si veda questo esempio:

https://vimeo.com/461561954

Per porre rimedio a questo tipo di inconvenienti possiamo utilizzare la direttiva v-cloak in combinazione con una relativa regola CSS. La direttiva v-cloak viene infatti rimossa dall’elemento su cui è stata applicata solo al termine della fase di compilazione eseguita dall’istanza Vue base.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Semplice Applicazione in Vue.js</title>
  <style>
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>

  <div id="app" v-cloak>
    <p>
      {{ msg }}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="app.js"></script>

</body>
</html>

Così facendo l’elemento sul quale viene applicata la direttiva v-cloak, che in questo caso è l’elemento base della nostra applicazione, verrà nascosto fino a quando non è stata completata la fase di compilazione.

https://vimeo.com/461561897

La direttiva v-bind

La tecnica dell’interpolazione non può essere tuttavia usata per gli attributi. Al contrario la direttiva v-bind permette di associare un attributo ad un’espressione javascript. Per esempio è possibile associare un attributo ad una delle proprietà definite nell’oggetto data di un’istanza Vue. Quando quest’ultima subisce una variazione, Vue provvede a passare il nuovo valore all’attributo a cui è collegata.

La sintassi richiesta dalla direttiva v-bind è la seguente.

Schema di funzionamento della direttiva v-bind

La direttiva v-bind viene applicata ad un elemento passando come argomento l’attributo che vogliamo venga aggiornato in maniera dinamica (Trascuriamo per ora il concetto delle ‘Props‘ che ci aiuteranno in seguito per trasferire delle informazioni ai componenti da noi definiti). La sintassi da usare per passare un argomento prevede l’uso dei due punti (‘:’) seguiti dal nome dell’attributo. Come valore useremo invece una singola espressione Javascript che sarà di volta in volta calcolata da Vue.js.

Facendo riferimento all’immagine in alto, ogni volta che il valore della proprietà imageSrc subisce una variazione, Vue provvederà ad aggiornare l’attributo src dell’elemento <img> su cui è applicata la direttiva v-bind.

Vediamo allora come usare la direttiva v-bind nel prossimo esempio in cui creiamo una nuova cartella avente la seguente struttura.

tree
.
├── app.js
├── imgs
│   ├── blue-house.jpg
│   └── home-real-estate.jpg
└── index.html

1 directory, 4 files

Nel file index.html ci limitiamo ad aggiungere un elemento <img> che fa uso della direttiva v-bind per aggiornare in maniera dinamica l’attributo src associandolo alla proprietà imgPath dell’istanza Vue base che abbiamo definito nel file app.js.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Semplice Applicazione in Vue.js</title>
  <style>
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>

  <div id="app" v-cloak>
    <img v-bind:src="imgPath" width="660" height="480"/>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="app.js"></script>

</body>
</html>

Il file app.js contiene invece il frammento di codice riportato sotto.

const vm = new Vue({
  el: '#app',
  data: {
    imgPath: 'imgs/blue-house.jpg'
  }
});

Visualizziamo così l’esempio appena illustrato nel browser affidandoci sempre a Live Server come negli esempi visti finora. Attraverso l’estensione Vue DevTools aggiorniamo il valore della proprietà vm.$data.imgPath in modo da puntare all’altra immagine ‘home-real-estate.jpg’ presente nella cartella imgs.

https://vimeo.com/461562048

Grazie alla direttiva v-bind il valore dell’attributo src viene quindi automaticamente aggiornato da Vue ogni volta che la proprietà vm.$data.imgPath subisce una modifica.

La direttiva v-bind è sicuramente una delle direttive che useremo di più nel corso dello sviluppo di una qualsiasi applicazione in Vue.js. Per questo motivo a partire dalla versione 2.6 del framework è stata introdotta una sintassi abbreviata che consente di anteporre semplicemente il carattere ‘:’ ad un attributo di un elemento. I due elementi HTML riportati nel frammento di codice sottostante sono quindi del tutto equivalenti.

<img v-bind:src="imgPath" />
<!-- v-bind shorthand syntax-->
<img :src="imgPath" />

Da questo momento in poi useremo sempre la sintassi abbreviata perché è più leggibile e sintetica.

La direttiva v-bind associata agli attributi ‘style’ e ‘class’

La direttiva v-bind e l’attributo ‘style’

La direttiva v-bind può essere associata all’attributo style per cambiare lo stile di un elemento in maniera dinamica. Esistono due tipi di sintassi: la prima fa uso di un oggetto Javascript, la seconda consente di applicare stili multipli attraverso l’utilizzo di array.

Partiamo dal primo caso in cui useremo dei normali oggetti Javascript. I nomi delle proprietà CSS possono essere espressi utilizzando sia la convenzione kebab-case (secondo questa convenzione, delle proprietà composte da più parole usano il simbolo ‘-‘ come separatore, per esempio ‘font-size’) che camelCase (proprietà composte unendo le parole tra loro e lasciando le loro iniziali maiuscole, per esempio ‘fontSize’). Nel primo caso è necessario includere il nome di una proprietà fra apici ({'font-size': '2em'} ). Per questo motivo è consigliato usare la convenzione camelCase.

<p :style="styleObject">
  Donec sed odio dui.
</p>
const vm = new Vue({
  el: '#app',
  data: {
    styleObject: {
      fontSize: '2em',
      fontWeight: 800,
      color: '#333435'
    }
  }
});
esempio della direttiva v-bind applicata all'attributo style

Ed in maniera dinamica possiamo modificare il valore delle proprietà dell’attributo style. Per il momento continuiamo a farlo tramite Vue DevTools in attesa di introdurre nella prossima lezione i concetti necessari per interagire con un’applicazione.

https://vimeo.com/461561876

Il secondo tipo di sintassi consente di applicare allo stesso elemento gli stili definiti in più oggetti. Per far ciò assegneremo a v-bind:style un array. Se due o più oggetti contengono le stesse proprietà, queste vengono sovrascritte dando precedenza a quelle presenti negli elementi dell’array di indice maggiore.

<div id="app">
  <p :style="[baseStyles, overridingStyles]">
    Donec sed odio dui.
  </p>
</div>
const vm = new Vue({
  el: "#app",
  data: {
    baseStyles: {
      fontSize: "2em",
      fontWeight: 800,
      color: "rgb(51, 52, 53)"
    },
    overridingStyles: {
      color: "rgb(21, 101, 192)"
    }
  }
});
esempio che fa uso della proprietà v-bind associata all'attributo style attraverso array

La direttiva v-bind e l’attributo ‘class’

Anche a v-bind:class possiamo assegnare un oggetto per attivare in modo dinamico una o più classi. Come nel caso dell’attributo style, l’oggetto può essere passato direttamente come valore o definendolo come proprietà dell’oggetto data di un’istanza. I due esempi mostrati sotto sono quindi equivalenti.

// Esempio 1
const vm = new Vue({
  el: "#app",
  data: {
    isEnabled: false,
    hasError: true
  }
});
<button 
  type="button" 
  class="btn" 
  :class="{ enabled: isEnabled, 'btn-warning': hasError }">
  Danger
</button>
// Esempio 2
const vm = new Vue({
  el: "#app",
  data: {
    classObject: {
      enabled: false,
      'btn-warning': true
    }
  }
});
<button type="button" class="btn" :class="classObject">
  Danger
</button>

Negli esempi mostrati sopra è presente un attributo class con valore statico. Per questo motivo gli elementi <button> avranno sempre una classe btn. Al contrario la presenza sugli elementi delle classi definite come proprietà degli oggetti assegnati a v-bind-class è determinata dal loro valore. In corrispondenza di un valore equiparabile al valore booleano true, la classe sarà aggiunta all’elemento del DOM. Per entrambi i pulsanti dell’esempio precedente otterremo quindi un elemento come quello riportato nell’esempio sottostante.

<button type="button" class="btn btn-warning">
  Danger
</button>

Infatti la proprietà ‘btn-warning’ ha in entrambi i casi valore true. Per questo motivo viene aggiunta alla lista delle classi dell’elemento. Al contrario ‘enabled’ ha valore iniziale false per cui non verrà assegnata all’elemento finché non assumerà valore true.

Anche a v-bind:class possiamo passare un array per applicare una lista di classi. Le classi nell’array possono essere definite direttamente tramite stringhe di testo o facendo riferimento a delle proprietà dell’istanza Vue.

<button type="button" :class="['btn', warningClass]" >
  Danger
</button>
const vm = new Vue({
  el: "#app",
  data: {
    warningClass: 'btn-warning',
  }
});

L’elemento <button> avrà anche in questo caso una lista di classi pari a "btn btn-warning".

<button type="button" class="btn btn-warning">
  Danger
</button>

Infine come elemento dell’array possiamo anche usare un oggetto per applicare una classe a seconda che il valore della relativa proprietà sia vero o falso.

<button type="button" :class="['btn', classObject]" >
  Danger
</button>
const vm = new Vue({
  el: "#app",
  data: {
    classObject: {
      enabled: false,
      'btn-warning': true
    }
  }
});

Anche in questo caso il pulsante finale presenterà sempre le due classi "btn btn-warning". La prima perché è un valore statico, la seconda perché alla proprietà 'btn-warning' dell’oggetto classObject è associato il valore true.

<button type="button" class="btn btn-warning">
  Danger
</button>

Conclusioni

In questa lezione abbiamo parlato del meccanismo di interpolazione dei dati e dell’uso della direttiva v-once per non aggiornare le informazioni mostrate in seguito alle modifiche fatte sui dati. Abbiamo introdotto altre direttive che possono essere utili nello sviluppo di un’applicazione come v-html e v-cloak. Abbiamo infine illustrato come rendere dinamici gli attributi di un elemento grazie alla direttiva v-bind e come utilizzare quest’ultima per aggiornare i valori degli attributi class e style.

Pubblicitร