Основной концепцией многих современных фреймворков и библиотек JavaScript является возможность инкапсулировать данные и пользовательский интерфейс в модульные повторно используемые компоненты. Это позволяет разработчикам избежать написания большого количества повторяющегося кода при разработке всего приложения. Хотя это очень полезно, это также включает обмен данными между компонентами. Эта концепция также существует в Vue. В течение предыдущего периода обучения передача данных компонента Vue часто имела компоненты «родитель-потомок» и передачу данных между одноуровневыми компонентами. Другими словами, в Vue существуют определенные принципы взаимодействия компонентов.
Принцип связи родительско-дочерний компонент
Чтобы улучшить независимость и возможность повторного использования компонентов, родительский компонент будет проходитьprops
Передайте данные дочернему компоненту, когда дочернему компоненту есть что сказать родительскому компоненту, он передаст$emit
События сообщают родительскому компоненту. Это гарантирует, что каждый компонент работает независимо в относительно изолированной среде, что может значительно повысить удобство сопровождения компонентов.
Эта часть подробно описана в статье «Общение компонентов Vue». Однако этот набор принципов связи имеет определенные критические замечания в отношении обмена данными между одноуровневыми компонентами. Конечно, есть и другие способы управления обменом данными между родственными компонентами в Vue, например библиотеки вроде Vuex. Но во многих случаях наше приложение не нуждается в такой библиотеке, как Vuex, для обработки обмена данными между компонентами, и может использовать Vue в автобус событий ,который **EventBus
**.
Следующий контент — совместное обучение во Vue.EventBus
соответствующие очки знаний.
Введение в EventBus
EventBus
Также известен как шина событий. Доступно в VueEventBus
Что касается концепции коммуникационного моста, то все компоненты используют один и тот же центр событий, вы можете зарегистрироваться в центре для отправки или получения событий, поэтому компоненты могут уведомлять другие компоненты параллельно, но это слишком удобно, поэтому, если вы используете это небрежно, это вызовет катастрофу, которую трудно поддерживать, поэтому необходим более полный Vuex в качестве центра управления состоянием, а концепция уведомления поднята до уровня общего состояния.
Как использовать EventBus
Как использовать его в проекте VueEventBus
Как насчет передачи данных между компонентами? В частности, это можно сделать с помощью следующих шагов.
инициализация
Первое, что вам нужно сделать, это создать шину событий и экспортировать ее, чтобы другие модули могли ее использовать или прослушивать. Мы можем справиться с этим двумя способами. Посмотрим на первый, создадим новый.js
файл, напримерevent-bus.js
:
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
Все, что вам нужно сделать, это импортировать Vue и экспортировать его экземпляр (в этом случае я назову егоEventBus
). По сути, это компонент, у которого нет DOM, все, что у него есть, — это методы экземпляра, поэтому он очень легкий.
Другой способ, можно прямо в проектеmain.js
инициализацияEventBus
:
// main.js
Vue.prototype.$EventBus = new Vue()
Обратите внимание, что инициализированный таким образомEventBus
Является глобальная шина событий. Позже мы потратим некоторое время на разговор о глобальной шине событий.
Теперь мы создалиEventBus
, следующее, что вам нужно сделать, это загрузить его в свой компонент и вызвать тот же метод, как если бы вы передавали сообщения друг другу в родительском и дочернем компонентах.
отправить событие
Предположим, у вас есть два подкомпонента:DecreaseCount
а также IncrementCount
, соответственно привязанный к кнопкеdecrease()
а также increment()
метод. То, что делают эти два метода, очень просто, то есть значение уменьшается (увеличивается)1
, а значение угла уменьшается (увеличивается)180
. В обоих методах поEventBus.$emit(channel: string, callback(payload1,…))
мониторdecreased
(а также incremented
) канал.
<!-- DecreaseCount.vue -->
<template>
<button @click="decrease()">-</button>
</template>
<script> import { EventBus } from "../event-bus.js";
export default {
name: "DecreaseCount",
data() {
return {
num: 1,
deg:180
};
},
methods: {
decrease() {
EventBus.$emit("decreased", {
num:this.num,
deg:this.deg
});
}
}
};
</script>
<!-- IncrementCount.vue -->
<template>
<button @click="increment()">+</button>
</template>
<script> import { EventBus } from "../event-bus.js";
export default {
name: "IncrementCount",
data() {
return {
num: 1,
deg:180
};
},
methods: {
increment() {
EventBus.$emit("incremented", {
num:this.num,
deg:this.deg
});
}
}
};
</script>
Пример выше, вDecreaseCount
а также IncrementCount
отправлено отдельноdecreased
а также incremented
канал. Затем нам нужно получить эти два события в другом компоненте, чтобы обеспечить обмен данными между компонентами.
получать события
Теперь мы можем в компонентеApp.vue
используется вEventBus.$on(channel: string, callback(payload1,…))
мониторDecreaseCount
а также IncrementCount
отправлено отдельноdecreased
а также incremented
канал.
<!-- App.vue -->
<template>
<div id="app">
<div class="container" :style="{transform: 'rotateY(' + degValue + 'deg)'}">
<div class="front">
<div class="increment">
<IncrementCount />
</div>
<div class="show-front"> {{fontCount}} </div>
<div class="decrement">
<DecreaseCount />
</div>
</div>
<div class="back">
<div class="increment">
<IncrementCount />
</div>
<div class="show-back"> {{backCount}} </div>
<div class="decrement">
<DecreaseCount />
</div>
</div>
</div>
</div>
</template>
<script>
import IncrementCount from "./components/IncrementCount";
import DecreaseCount from "./components/DecreaseCount";
import { EventBus } from "./event-bus.js";
export default {
name: "App",
components: {
IncrementCount,
DecreaseCount
},
data() {
return {
degValue:0,
fontCount:0,
backCount:0
};
},
mounted() {
EventBus.$on("incremented", ({num,deg}) => {
this.fontCount += num
this.$nextTick(()=>{
this.backCount += num
this.degValue += deg;
})
});
EventBus.$on("decreased", ({num,deg}) => {
this.fontCount -= num
this.$nextTick(()=>{
this.backCount -= num
this.degValue -= deg;
})
});
}
};
</script>
Окончательный результат выглядит следующим образом:
Наконец, изображение используется для описания используемого в примереEventBus
Отношение между:
Если вы хотите только прослушать возникновение события, вы можете использоватьEventBus.$once(channel: string, callback(payload1,…))
.
удалить прослушиватель событий
Если вы хотите удалить прослушиватели событий, вы можете сделать следующее:
import { eventBus } from './event-bus.js'
EventBus.$off('decreased', {})
Вы также можете использоватьEventBus.$off(‘decreased’)
чтобы удалить всех прослушивателей этого события в приложении. или позвоните напрямуюEventBus.$off()
чтобы удалить все каналы событий,Обратите внимание, что никаких параметров добавлять не нужно..
вышеEventBus
Как им пользоваться не очень просто. Мы также видели в приведенном выше примере, что каждый раз, когда мы используемEventBus
необходимо ввести в каждый компонентevent-bus.js
. На самом деле, есть и другие способы упростить задачу. То есть создать глобальнуюEventBus
. В следующем примере показано, как создать глобальный объект в проекте Vue.EventBus
.
Глобальная шина событий
Глобальная шина EventBus, хотя в некоторых примерах и не рекомендуется, является очень изящным и простым способом обмена данными между компонентами.
Он работает на основе подхода публикации/подписки, обычно называемогоPub/Sub
.
Весь этот подход можно рассматривать как шаблон проектирования, потому что, если вы посмотрите вокруг, это скорее архитектурное решение. Мы будем использовать простой JavaScript, создадим два компонента и продемонстрируем, как работает EventBus.
Давайте взглянем на изображение ниже и попробуем понять, что именно происходит в этой ситуации.
Из приведенного выше рисунка можно сделать следующие выводы:
- Существует глобальный EventBus
- все события подписываются на него
- Все компоненты также публикуются в нем, а подписавшиеся компоненты получают обновления
- В заключение. Все компоненты могут публиковать события в шине, затем шина подписывается другим компонентом, затем компонент, подписанный на него, будет обновляться.
В коде мы будем держать его очень маленьким и лаконичным. Мы разделим его на две части и покажем два компонента и код для создания шины событий.
Создайте глобальную шину событий
Глобальная шина событий — не что иное, как простаяvue
компонент. код показывает, как показано ниже:
var EventBus = new Vue();
Object.defineProperties(Vue.prototype, {
$bus: {
get: function () {
return EventBus
}
}
})
Теперь эта конкретная шина использует два метода$on
а также $emit
. Один используется для создания испускаемого события, которое$emit
; другой для подписки$on
:
var EventBus = new Vue();
this.$bus.$emit('nameOfEvent',{ ... pass some event data ...});
this.$bus.$on('nameOfEvent',($event) => {
// ...
})
Теперь давайте создадим два простых компонента для окончательного вывода.
В следующем примере мы создаемShowMessage
Компонент используется для отображения информации, а дополнительныйUpdateMessage
Компонент , используемый для обновления информации.
существует UpdateMessage
Запустите необходимое событие в компоненте. В этом примереupdateMessage
событие, это событие отправленоupdateMessage
канал:
<!-- UpdateMessage.vue -->
<template>
<div class="form">
<div class="form-control">
<input v-model="message" >
<button @click="updateMessage()">更新消息</button>
</div>
</div>
</template>
<script>
export default {
name: "UpdateMessage",
data() {
return {
message: "这是一条消息"
};
},
methods: {
updateMessage() {
this.$bus.$emit("updateMessage", this.message);
}
},
beforeDestroy () {
$this.$bus.$off('updateMessage')
}
};
</script>
в то же времяShowMessage
Компонент прослушивает это событие:
<!-- ShowMessage.vue -->
<template>
<div class="message">
<h1>{{ message }}</h1>
</div>
</template>
<script>
export default {
name: "ShowMessage",
data() {
return {
message: "我是一条消息"
};
},
created() {
var self = this
this.$bus.$on('updateMessage', function(value) {
self.updateMessage(value);
})
},
methods: {
updateMessage(value) {
this.message = value
}
}
};
</script><
Окончательный эффект выглядит следующим образом:
Из приведенного выше кода мы видим, чтоShowMessage
Компонент прослушивает файл с именемupdateMessage
Определенное событие, которое запускается при создании экземпляра компонента, или вы можете запустить его при создании компонента. С другой стороны, у нас есть еще один компонентUpdateMessage
, у которого есть кнопка, которая генерирует событие, когда кто-то нажимает на нее. Это заставляет компонент подписки прослушивать испускаемые события. Это производитPub/Sub
Модель, которая сохраняется среди братьев и сестер и очень проста в реализации.
Суммировать
Эта статья в основном изучает Vue на двух примерах.EventBus
соответствующие очки знаний. в основном участвуютEventBus
Как создать экземпляр и как передать$emit
Отправить сигнал канала, и как передать$on
для приема сигнала канала. Наконец, краткое введение в то, как создать глобальнуюEventBus
. Из примеров мы видим, чтоEventBus
Это может лучше реализовать передачу данных между одноуровневыми компонентами.