Vue.js全局事件总线
Vue.js global event bus
我正在尝试创建一个全局事件总线,以便两个兄弟组件可以相互通信。我已经四处搜索;然而,我找不到任何例子如何实现一个。这是我目前所看到的:
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()
做错了什么。
问题是在您的bus.$on
函数中,this
指的是总线。您只需要使用.bind()
:
bus.$on('inc', function(num){
alert(num)
this.count = num;
}.bind(this));
如果你想管理全局应用程序状态,你还应该查看https://github.com/vuejs/vuex。
编辑:由于这个页面似乎得到了很多点击,我想编辑和添加另一个方法,per ChristopheMarois在评论中:
编辑:为了使这个答案更清楚一些,这样以后的读者就不需要阅读评论了,下面是发生的事情:
使用像下面这样的粗箭头将'this'的词法范围绑定到组件而不是事件总线。
bus.$on('inc', (num) => {
alert(num);
this.count = num;
});
或者删除警告:
bus.$on('inc', (num) => this.count = num);
当你编写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
这是回答很久以前,这是我的解决方案使用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>
这个怎么样?假设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)
作为一个边注,尝试使用事件总线模式作为最后的手段。
- 分派点击事件并保留击键修饰符
- 模糊事件的Javascript测试
- keyup事件处理程序更改焦点不适用于快速键入
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 如何使Javascript动态html表及其上的事件
- 使用类从一个标记中双击事件
- 如何在未直接触发的情况下停止事件
- 如何在elfinder插件(一个文件管理器插件)上获得上传前事件
- 对iPad上的点击事件反应缓慢
- 事件和状态
- Fancybox是否将Click事件静音
- 主干-不管怎样,检查事件以前是否绑定过
- SAPUI5 事件总线:防止堆叠相同的订阅
- 连接总线男孩 on('file') 事件未触发
- 角度模块中的全局通信:事件总线或调解器模式/服务
- 杀戮观点,全球事件总线. 骨干
- Vertx事件总线访问_denied
- 独特的主干事件总线,也可以共享全局事件
- Javascript事件总线架构
- Vue.js全局事件总线