Components: eventi custom

31 ottobre 2017

Grazie alla definizione di eventi custom, è possibile comunicare qualcosa a partire da un componente verso l’esterno. Ogni componente presenta due metodi: $on e $emit, rispettivamente per mettersi in ascolto o per generare un evento. Spesso, come vedremo, l’utilizzo del metodo $on verrà sostituito dalla direttiva v-on.

Guardiamo un esempio riprendendo lo snippet della lezione precedente:

Vue.component('child-component', {
  props: ['firstname', 'lastname'],
  methods: {
    updateFirstname: function() {
      this.$emit('update-firstname', 'luigi');
    }
  }
});
new Vue({
  el: '#vue-app',
  data: {
    firstname: 'alberto',
    lastname: 'bottarini'
  },
  methods: {
    onUpdateFirstname: function(newFirstname) {
      this.firstname = newFirstname;
    }
  }
});
<div id="vue-app"> 
  <b>{{ firstname }} {{ lastname }}</b>
  <child-component inline-template :firstname="firstname" :lastname="lastname" @update-firstname="onUpdateFirstname"> 
    <button @click="updateFirstname()">Update from child</button> 
  </child-component> 
</div>

Rispetto all’esempio precedente, abbiamo modificato il comportamento della funzione updateFirstname associata al pulsante: al posto di modificare il parametro firstname, emette un evento update-firstname che viene ascoltato grazie alla direttiva @update-firstname dall’istanza padre di Vue che ha modo di modificare quindi il name. Modifica che poi verrà automaticamente propagata al componente figlio grazie alla classica comunicazione monodirezionale approfondita in precedenza.

Dato che l’esigenza di propagare modifiche di dati da un componente verso il padre è frequente, gli sviluppatori di Vue hanno introdotto dalla versione 2.3.0 il modificatore sync che permette di implementare lo stesso pattern dell’esempio precedente in maniera più veloce e senza la necessità di scrivere metodi ad hoc. Il modificatore rappresenta una sorta di scorciatoria che evita di definire il metodo, nel componente padre, che modifica la variabile originale (rifacendoci all’esempio precedente, rende inutile la scrittura del metodo onUpdateFirstname). Guardiamo un esempio:

Vue.component('child-component', {
  props: ['firstname', 'lastname'],
  methods: {
    updateFirstname: function() {
      this.$emit('update:firstname', 'luigi');
    }
  }
});
new Vue({
  el: '#vue-app',
  data: {
    firstname: 'alberto',
    lastname: 'bottarini'
  }
});
<div id="vue-app"> 
  <b>{{ firstname }} {{ lastname }}</b>
  <child-component inline-template :firstname.sync="firstname" :lastname="lastname"> 
    <button @click="updateFirstname()">Update from child</button> 
  </child-component> 
</div>

La modifica, seppur banale, permette di abbreviare il codice scritto. Una nota importante va spesa in merito al nome dell’evento. Se nel primo esempio eravamo completamente liberi rispetto al nome evento da utilizzare (bastava infatti che il listener fosse coerente con l’emit), nel caso del modificatore sync l’evento deve avere la sintassi update:{nomecampo}, questo perchè è necessaria una sintassi generico, disponibile a prescindere dall’esempio stesso.

Analoga al modificatore sync è la direttiva v-model, che permette di creare componenti che rappresentano dei custom input, come ad esempio un selettore di date o uno slider personalizzato. La direttiva permette di recuperare il dato tramite la prop speciale value e richiede l’utilizzo di un custom event input per aggiornare il modello verso l’esterno del componente.

Comunicazione tra componenti non correlati

Nei primi due paragrafi del capitolo abbiamo definito la modalità di comunicazione tra un componente padre e uno figlio. Il pattern suggerito dagli sviluppatori è definito come props down, events up in quanto la comunicazione verso il basso è implementata tramite passaggio di props, mentre la comunicazione opposta tramite eventi.

Spesso però può capitare che sia necessario far comunicare tra di loro componenti che non sono a “stretto contatto”. Per queste casistiche, la soluzione proposta degli sviluppatori Vue è quella di creare una istanza extra di Vue che funga da bus di eventi sul quale qualsiasi componente interessato ad un determinato evento potrebbe mettersi in ascolto.

Ecco un esempio esplicativo:

Vue.component('incrementer', {
  template: '<button @click="increment">+</button>',
  methods: {
    increment: function() {
      EventBus.$emit('increment');
    }
  }
});

var EventBus = new Vue();

new Vue({
  el: '#vue-app',
  data: {
    counter: 0
  },
  created: function() {
    var that = this;
    EventBus.$on('increment', this.increment.bind(this));
  },
  methods: {
    increment: function() {
      this.counter++;
    }
  }
});
<div id="vue-app"> 
  <b>{{ counter }} </b>
  <incrementer></incrementer> 
  <incrementer></incrementer> 
  <incrementer></incrementer> 
  <incrementer></incrementer> 
</div>

Tutte le lezioni

1 ... 11 12 13

Se vuoi aggiornamenti su Components: eventi custom inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Components: eventi custom

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy