Vue.js
evenemang
Sök…
Händelssyntax
För att skicka en händelse: vm.$emit('new-message');
För att fånga en händelse: vm.$on('new-message');
För att skicka en händelse till alla komponenter ner : vm.$broadcast('new-message');
För att skicka en händelse till alla komponenter upp : vm.$dispatch('new-message');
Obs: $broadcast
och $dispatch
skrivs ut i Vue2. ( se Vue2-funktioner )
När ska jag använda händelser?
Följande bild illustrerar hur komponentkommunikation ska fungera. Bilden kommer från The Progressive Framework- bilder från Evan You (Developer of VueJS).
Här är ett exempel på hur det fungerar:
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
}
});
Exemplet ovan kan förbättras!
Exemplet ovan visar hur komponentkommunikationen fungerar. Men i fallet med en anpassad inmatningskomponent, för att synkronisera överordnad variabel med det skrivna värdet, ska vi använda v-model
.
I Vue1 bör du använda .sync
på propellen som skickas till <message-box>
-komponenten. Detta berättar för VueJS att synkronisera värdet i barnkomponenten med förälderns.
Kom ihåg: Varje komponentinstans har sin egen isolerade omfattning.
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>
I Vue2 finns det en speciell 'input'
-händelse som du kan $emit
. Genom att använda denna händelse kan du sätta en v-model
direkt på <message-box>
-komponenten. Exemplet ser ut som följer:
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
}
});
Lägg märke till hur snabbare ingången uppdateras.
Hur hanteras avskrivning av $ sändning och $ sändning? (busshändelsemönster)
Du kanske har insett att $emit
skopas till den komponent som avger händelsen. Det är ett problem när du vill kommunicera mellan komponenter långt ifrån varandra i komponentträdet.
Obs: I Vue1 använder du $dispatch
eller $broadcast
, men inte i Vue2. Anledningen är att den inte skalas bra. Det är en populär bus
mönster för att hantera detta:
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
}
});
Du behöver bara förstå att varje Vue()
-instans kan $emit
och fånga ( $on
) en händelse. Vi förklarar bara en global Vue
instans samtals bus
och sedan någon komponent med denna variabel kan avge och fånga händelser från det. Se bara till att komponenten har tillgång till bus
variabel.