Vue.js
События
Поиск…
Синтаксис событий
Чтобы отправить событие: vm.$emit('new-message');
Чтобы поймать событие: vm.$on('new-message');
Для того, чтобы отправить событие для всех компонентов вниз: vm.$broadcast('new-message');
. vm.$broadcast('new-message');
Чтобы отправить событие всем компонентам вверх : vm.$dispatch('new-message');
Примечание: $broadcast
и $dispatch
устарели в Vue2. ( см. функции Vue2 )
Когда следует использовать события?
На следующем рисунке показано, как взаимодействие компонентов должно работать. Изображение происходит от слайдов Progressive Framework от Evan You (разработчика VueJS).
Вот пример того, как это работает:
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
}
});
Приведенный выше пример можно улучшить!
В приведенном выше примере показано, как работает компонентная связь. Но в случае пользовательского компонента ввода, чтобы синхронизировать родительскую переменную с введенным значением, мы можем использовать v-model
.
В Vue1 вы должны использовать .sync
на опоре, отправленном в компонент <message-box>
. Это указывает VueJS синхронизировать значение в дочернем компоненте с родительским.
Помните: каждый экземпляр компонента имеет свою изолированную область.
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>
В Vue2 есть специальное событие 'input'
которое вы можете $emit
. Использование этого события позволяет поместить v-model
непосредственно в компонент <message-box>
. Пример будет выглядеть следующим образом:
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
}
});
Обратите внимание, как быстрее обновляется вход.
Как бороться с устареванием $ dispatch и $ broadcast? (шаблон события шины)
Возможно, вы поняли, что $emit
привязан к компоненту, который испускает событие. Это проблема, когда вы хотите общаться между компонентами, расположенными далеко друг от друга в дереве компонентов.
Примечание. В Vue1 вы можете использовать $dispatch
или $broadcast
, но не в Vue2. Причина в том, что он плохо масштабируется. Существует популярный шаблон bus
для управления этим:
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
}
});
Вам просто нужно понять, что любой экземпляр Vue()
может $emit
и catch ( $on
) событие. Мы просто объявляем глобальную bus
вызовов экземпляра Vue
а затем любой компонент с этой переменной может испускать и извлекать из нее события. Просто убедитесь, что компонент имеет доступ к переменной bus
.