我正在尝试创建一个全局事件总线,以便两个兄弟组件可以相互通信。我四处寻找;但是,我找不到任何实现方法的例子。这就是我到目前为止所做的:
var bus = new Vue();
Vue.component('Increment', {
template: "#inc",
data: function() {
return ({count: 0})
},
methods: {
increment: function(){
var increment = this.count++
bus.$emit('inc', increment)
}
}
})
Vue.component('Display', {
template: "#display",
data: function(){
return({count: 0})
},
created: function(){
bus.$on('inc', function(num){
alert(num)
this.count = num;
});
}
})
vm = new Vue({
el: "#example",
})
我创建了我的模板:http://codepen.io/p-adams/pen/PzpZBg
我希望Increment
组件将计数传达给Display
组件。我不确定bus.$on()
中我做错了什么。
答案 0 :(得分:30)
问题是在bus.$on
函数中,this
指的是总线。您只需要使用.bind()
将当前Vue实例绑定到该函数:
bus.$on('inc', function(num){
alert(num)
this.count = num;
}.bind(this));
如果要管理全局应用程序状态,还应该查看https://github.com/vuejs/vuex。
编辑:由于此页面似乎获得了大量点击,我想编辑并添加另一种方法,根据评论中的每个ChristopheMarois:
bus.$on('inc', (num) => {
alert(num);
this.count = num;
});
或删除提醒:
bus.$on('inc', (num) => this.count = num);
答案 1 :(得分:3)
在编写ES5 JavaScript时,您必须注意这样一个事实:使用this
关键字引用的内容可能会发生变化,根据范围,它会被调用。
让你了解this
概念的一个有用的比喻是将ES5中的花括号视为围栏,它包含/绑定自己的this
。
在事件总线的回调函数中使用this
时,this
不是指您的Vue组件,而是总线对象,它没有计算数据,因此您希望更新的数据不会。
如果您有/想要编写ES5语法,常见的解决方法(除了接受的答案所建议的绑定this
)是将this
关键字分配给变量,如下所示:
created: function(){
var self = this;
bus.$on('inc', function(num){
alert(num)
self.count = num;
});
}
如果您可以编写ES6,请尽可能这样做。您始终可以使用Babel编译/转换为ES5。接受的答案将向您展示如何使用箭头功能。
箭头函数在这种情况下起作用,因为它们不绑定自己的this
。
坚持使用围栏隐喻:想象ES6箭头在功能栏中戳一个洞,因此外部this
可以通过,你可以按预期调用this
。
要了解有关ES6箭头功能的更多信息,请访问: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
答案 2 :(得分:3)
这是很久以前的回答,这是我在vue.js-2中使用的解决方案
<强> main.js 强>
import Vue from 'vue'
import App from './App'
export const eventBus = new Vue({
methods:{
counter(num) {
this.$emit('addNum', num);
}
}
});
new Vue({
el: '#app',
template: '<App/>',
components: { App }
});
<强> comp1.vue 强>
//Calling my named export
import { eventBus } from '../../main'
<template>
<div>
<h1>{{ count }}</h1>
<button @click="counterFn">Counter</button>
</div>
</template>
<script>
import { eventBus } from '../../main'
export default {
name: 'comp-one',
data() {
return {
count: 0
}
},
methods: {
counterFn() {
eventBus.counter(this.count);
}
},
created() {
eventBus.$on('addNum', () => {
this.count++;
})
}
}
</script>
答案 3 :(得分:0)
这个怎么样?假设Vue.js 2。
创建可重用的Event-Bus组件,并通过插件模式将其附加到Vue
:
// ./components/EventBus.vue
import Vue from 'vue'
export const EventBus = new Vue()
// ./plugins/EventBus.js
export default {
install(Vue) {
const { EventBus } = require('../components/EventBus')
Vue.prototype.$bus = EventBus
}
}
// ./main.js
import EventBus from './plugins/EventBus'
Vue.use(EventBus)
然后,您可以在代码中的任何位置执行操作:
this.$bus.$emit('some-event', payload)
作为旁注,请尝试使用Event-Bus模式作为最后的手段。