Event Bus - это нормально, но проблема в реализации.
Вы очень правы, если вы un-comment code
В домашнем компоненте, который я тестировал на вашем фрагменте, он испускает только один раз event bus test
[консоль.log]
С событиями вам нужно позаботиться об этом
- Необходимо определить слушателя.[убедитесь, что вы определили их перед отправкой события]
- Теперь вы просто отправляете событие.[для работы нам нужно, чтобы слушатель слушал первым]
В вашем случае вы написали listener function $on
в created
событии Test2Component
Теперь просто подумайте, Выу вас нет слушателей в начале, как в home compo
, вы только что прокомментировали этот код слушателя. [его начальный шаг]
Теперь, когда вы нажимаете кнопку click me
, вы changing
компонент для нового компонента [Test2Component], он монтируется и его событие created
сработает then this listener will start listening to event
, но вы пропустили это
this.$emit("changeComponent"); // this is first [ fires/emit ]
this.$bus.$emit("test"); // THEN THIS EMIT
Итак, когда это простозапуск changing
компонент из compo1 to
compo2
тест fired/emitted directly without wait, its not
синхронный it is
A синхронный It will not wait to finish all stuff of
changeComponent . It will be emitted immediately [
test`]
Угадайте, что Теперь, когда test
испускает, в это время Dom operation to add component, ITS NOT DONE YET
, и test
испускается
Итак, No listeners are there
, поэтому нет console.log
Но если вы видите, что вы UNCOMMENT listener
в слушателе домашней функции хорошо определены до emit of test event
, так что он выводится в консоли.
Я надеюсь, вы понимаете, если нет, дайте мне знатьЯ будуЯ объясню это более подробно
Еще одно, что вы добавили $ bus в prototype
, чтобы все компоненты имели свою собственную шину.вместо этого вы можете использовать GLOBAL event Bus
, как в примере, который вы видите.
в es6 вы можете сделать
//bus.js
const bus = new Vue({});
export default bus;
, чтобы импортировать его в другие компоненты
import bus from './bus.js';
// ... do bus.$on ..
// ... do bus.$emit ..
var $bus = new Vue({});
Vue.component('Test1', {
template: `
<div class="blog-post">
<h3>test1</h3>
<button @click="changeComponent">click me</button>
</div>
`,
methods: {
changeComponent() {
$bus.$emit("chng");
$bus.$emit("test");
}
}
});
Vue.component('Test2', {
template: `
<div class="blog-post">
<h3>test2</h3>
</div>
`,
created() {
$bus.$on("test", () => console.log("test in test2 will not fire as we are little late to listen it"));
}
});
new Vue({
el: '#app',
created: function(){
console.log('created');
$bus.$on("chng", () => this.changeComponent());
$bus.$on("test", () => console.log("test in test2 main/HOME"));
},
data() {
return {
currentComponent: "Test1"
};
},
methods: {
changeComponent() {
this.currentComponent = "Test2";
}
}
});
<!DOCTYPE html>
<html>
<head>
<script> console.info = function(){} </script>
<script src="https://code.jquery.com/jquery.min.js"></script>
<script src="https://vuejs.org/js/vue.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Stack Overflow - Hardik Satasiya</title>
<style>.half{width:50%;float:left;}</style>
</head>
<body>
<div id="app">
<component :is="currentComponent" @changeComponent="changeComponent"></component>
</div>
</body>
</html>