Vue.js
Evenementen
Zoeken…
Syntaxis van evenementen
Om een evenement te verzenden: vm.$emit('new-message');
Om een evenement te vangen: vm.$on('new-message');
Als u een afspraak te sturen naar alle onderdelen neer: vm.$broadcast('new-message');
Als u een afspraak te sturen naar alle componenten up: vm.$dispatch('new-message');
Opmerking: $broadcast
en $dispatch
zijn verouderd in Vue2. ( zie Vue2-functies )
Wanneer moet ik evenementen gebruiken?
De volgende afbeelding illustreert hoe componentcommunicatie zou moeten werken. De foto komt van de dia's van The Progressive Framework van Evan You (ontwikkelaar van VueJS).
Hier is een voorbeeld van hoe het werkt:
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
}
});
Het bovenstaande voorbeeld kan worden verbeterd!
Het bovenstaande voorbeeld laat zien hoe de componentcommunicatie werkt. Maar in het geval van een aangepaste invoercomponent, zouden we de v-model
gebruiken om de bovenliggende variabele te synchroniseren met de getypte waarde.
In Vue1 moet u .sync
op de prop die naar de component <message-box>
verzonden. Dit vertelt VueJS om de waarde in de onderliggende component te synchroniseren met die van de ouder.
Onthoud: elke componentinstantie heeft zijn eigen geïsoleerde scope.
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 is er een speciale 'input'
invoer'-gebeurtenis die je kunt $emit
. Met behulp van deze gebeurtenis kunt u een v-model
rechtstreeks op de component <message-box>
. Het voorbeeld ziet er als volgt uit:
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
}
});
Merk op hoe sneller de invoer wordt bijgewerkt.
Hoe omgaan met afschrijving van $ verzending en $ uitzending? (bus evenement patroon)
Je hebt je misschien gerealiseerd dat $emit
zich uitstrekt tot het onderdeel dat het evenement uitzendt. Dat is een probleem wanneer u tussen componenten ver van elkaar in de componentenboom wilt communiceren.
Opmerking: in Vue1 kunt u $dispatch
of $broadcast
, maar niet in Vue2. De reden is dat het niet goed schaalt. Er is een populaire bus
patroon om dit te beheren:
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
}
});
Je moet gewoon begrijpen dat elke instantie van Vue()
$on
een evenement kan $emit
en vangen ( $on
). We declareren gewoon een globale Vue
instantie- bus
en vervolgens kan elk onderdeel met deze variabele gebeurtenissen uitzenden en vangen. Zorg ervoor dat de component heeft toegang tot de bus
variabele.