Vue.js
eventi
Ricerca…
Sintassi degli eventi
Per inviare un evento: vm.$emit('new-message');
Per catturare un evento: vm.$on('new-message');
Per inviare un evento a tutti i componenti in basso : vm.$broadcast('new-message');
Per inviare un evento a tutti i componenti up : vm.$dispatch('new-message');
Nota: $broadcast
e $dispatch
sono deprecati in Vue2. ( vedi le funzionalità di Vue2 )
Quando dovrei usare gli eventi?
La seguente immagine illustra come dovrebbe funzionare la comunicazione dei componenti. L'immagine proviene dalle diapositive di Progressive Framework di Evan You (sviluppatore di VueJS).
Ecco un esempio di come funziona:
HTML
<script type="x-template" id="message-box">
<input type="text" v-model="msg" @keyup="$emit('new-message', msg)" />
</script>
<message-box :msg="message" @new-message="updateMessage"></message-box>
<div>You typed: {{message}}</div>
JS
var messageBox = {
template: '#message-box',
props: ['msg']
};
new Vue({
el: 'body',
data: {
message: ''
},
methods: {
updateMessage: function(msg) {
this.message = msg;
}
},
components: {
'message-box': messageBox
}
});
L'esempio sopra può essere migliorato!
L'esempio sopra mostra come funziona la comunicazione del componente. Ma nel caso di un componente di input personalizzato, per sincronizzare la variabile padre con il valore digitato, dovremmo usare v-model
.
In Vue1, dovresti usare .sync
sul puntello inviato al componente <message-box>
. Questo dice a VueJS di sincronizzare il valore nel componente figlio con quello del genitore.
Ricorda: ogni istanza del componente ha il proprio ambito isolato.
HTML Vue1
<script type="x-template" id="message-box">
<input v-model="value" />
</script>
<div id="app">
<message-box :value.sync="message"></message-box>
<div>You typed: {{message}}</div>
</div>
In Vue2, c'è un evento speciale 'input'
che puoi $emit
. L'utilizzo di questo evento ti consente di mettere un v-model
direttamente sul componente <message-box>
. L'esempio avrà il seguente aspetto:
HTML Vue2
<script type="x-template" id="message-box">
<input :value="value" @input="$emit('input', $event.target.value)" />
</script>
<div id="app">
<message-box v-model="message"></message-box>
<div>You typed: {{message}}</div>
</div>
JS Vue 1 & 2
var messageBox = {
template: '#message-box',
props: ['value']
};
new Vue({
el: '#app',
data: {
message: ''
},
components: {
'message-box': messageBox
}
});
Nota quanto più veloce è l'aggiornamento dell'aggiornamento.
Come gestire la deprecazione di $ spedizione e $ broadcast? (modello di evento bus)
Potresti aver capito che $emit
come ambito il componente che sta emettendo l'evento. Questo è un problema quando si desidera comunicare tra componenti distanti l'uno dall'altro nell'albero dei componenti.
Nota: in Vue1 si usa $dispatch
o $broadcast
, ma non in Vue2. Il motivo è che non scala bene. C'è un modello di bus
popolare per gestirlo:
HTML
<script type="x-template" id="sender">
<button @click="bus.$emit('new-event')">Click me to send an event !</button>
</script>
<script type="x-template" id="receiver">
<div>I received {{numberOfEvents}} event{{numberOfEvents == 1 ? '' : 's'}}</div>
</script>
<sender></sender>
<receiver></receiver>
JS
var bus = new Vue();
var senderComponent = {
template: '#sender',
data() {
return {
bus: bus
}
}
};
var receiverComponent = {
template: '#receiver',
data() {
return {
numberOfEvents: 0
}
},
ready() {
var self = this;
bus.$on('new-event', function() {
++self.numberOfEvents;
});
}
};
new Vue({
el: 'body',
components: {
'sender': senderComponent,
'receiver': receiverComponent
}
});
Devi solo capire che ogni istanza di Vue()
può $emit
e prendere ( $on
) un evento. Dichiariamo solo un bus
chiamata di istanze Vue
globale e quindi qualsiasi componente con questa variabile può emettere e catturare eventi da esso. Assicurati solo che il componente abbia accesso alla variabile del bus
.