Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在vue.js 1.0.x中使用全局事件总线?_Vue.js - Fatal编程技术网

如何在vue.js 1.0.x中使用全局事件总线?

如何在vue.js 1.0.x中使用全局事件总线?,vue.js,Vue.js,我正在尝试使用空的新Vue实例创建事件总线。该应用程序足够大,可以拆分为多个组件文件。例如,我的应用程序结构如下: main.js 组件/update-user.js 组件/用户-list.js 组件/edit-user.js 组件/user-address.js index.html 。。。 ... 我的问题是为什么bus.$on只在第一个子组件中工作?即使我将侦听器从中删除,其他组件都无法通过总线侦听事件,即console.log()。下/后的任何组件(即直接子组件) 我是不是错过了什么或

我正在尝试使用空的
新Vue
实例创建事件总线。该应用程序足够大,可以拆分为多个组件文件。例如,我的应用程序结构如下:

main.js 组件/update-user.js 组件/用户-list.js 组件/edit-user.js 组件/user-address.js index.html
。。。
...
我的问题是为什么
bus.$on
只在第一个子组件中工作?即使我将侦听器从
中删除,其他组件都无法通过总线侦听事件,即
console.log()。
下/后的任何组件(即直接子组件)

我是不是错过了什么或者哪里做错了?

如何使此功能正常工作,以便任何深度的任何子组件都可以侦听从根组件或层次结构中更高位置发出的事件,反之亦然?

当侦听器被触发时,事件传播停止。如果希望事件继续,只需从侦听器返回
true


$emit
在实例范围内分派事件-它不会传播到父/子对象<代码>$broadcast
将传播到子组件。正如在的回答中提到的,中间组件事件回调必须返回
true
,以允许事件继续级联到[其]子级


var child=Vue.extend({
模板:“#子模板”,
数据:函数(){
返回{
通知:错误
}
},
活动:{
“global.event”:函数(){
this.notified=true;
返回true;
}
}
});
var child\u of_child=Vue.extend({
数据:函数(){
返回{
通知:错误
}
},
模板:“#子模板的子模板”,
活动:{
“global.event”:函数(){
this.notified=true;
}
}
});
Vue.组件(‘子’,子);
Vue.组件(“子对象的子对象”,子对象的子对象);
var parent=新的Vue({
el:“#包装器”,
数据:{
通知:错误
},
方法:{
广播:功能(){
此.$broadcast('global.event');
},
emit:function(){
此.emit('global.event');
}
},
活动:{
“global.event”:函数(){
this.notified=true;
}
}
});

已通知父项:{{notified}}
$broadcast
$emit
已通知子组件:{{notified}}
已通知子组件的子组件:{{notified}

我想出了办法,让它工作起来了。张贴在这里是为了帮助其他人谁点击这个问题

实际上,我在上面的问题中提到的实现没有什么问题。我试图在一个组件中侦听事件,该组件在触发事件时尚未呈现(v-if条件为false)。因此,一秒钟后(事件触发后),当组件呈现时,它无法侦听事件-这是Vue中的预期行为(我在laracasts论坛上得到了回复)

然而,我最终实现它的方式略有不同(基于以下建议:

import Vue from vue;

var bus = new Vue({});

Object.defineProperty(Vue.prototype, $bus, {
    get(){
        return this.$root.bus;
    }
});  

Vue.component('update-user', require('./components/update-user');
Vue.component('users-list', require('./components/users-list');
Vue.component('edit-user', require('./components/edit-user');
Vue.component('user-address', require('./components/user-address');

new Vue({
    el:'body',
    ready(){

    },
    data:{
       bus:bus
    }
});   
现在要从任何组件访问事件总线,我可以使用
this.$bus
as

this.$bus.$emit('custom-event', {message:'This is a custom event'});  
我可以从任何其他组件,比如

this.$bus.$on('custom-event', event => {
    console.log(event.message);  
    //or I can assign the message to component's data property  
    this.message = event.message;  

    //if this event is intended to be handled in other components as well
    //then as we normally do we need to return true from here  
    return true;
});

是的,我知道,所以我从
组件中删除了侦听器,但它仍然不起作用,我的意思是,即使我从第一个直接子级(即
)中删除了侦听器,并且在第二个直接子级(即
)上有一个侦听器,这里的事件侦听器也不会捕获事件并响应,即
console.log('Event message:'+msg)
中不输出任何内容。我甚至尝试使用
$broadcast
发出事件。顺便说一句,
组件只有在从
中进行选择后才会实例化。在我玩游戏时,我将事件发出包装在setTimeout()中,作为
setTimeout(()=>{bus.$emit('test-event','这是来自更新用户的测试事件');},5000)
组件中的
,然后从
组件中进行选择,该组件满足
v-if
条件,因此它在发出事件之前被实例化。现在我能够捕获事件并将消息记录到控制台。这意味着不在当前范围内的任何组件(即尚未实例化)即使事件仍然存在于总线中,也无法捕获在实例化之前发出的事件-我的理解正确吗?我正在尝试使用一个单独的空Vue实例作为事件总线,因此我认为
$broadcast/$dispatch/$emit
不会有任何区别,因为就
总线
vm而言这里没有孩子。如果不是,请告诉我。也请看看我对杰夫答案的评论并提出建议。谢谢
export default{
    template:require('./edit-user.template.html'),
    ready(){
        bus.$on('test-event', (msg) => {console.log('Event message: '+msg)});
        //doesn't output anything
        console.log(bus) //output shows vue instance with _events containing 'test-event'
    }
}
export default{
    template:require('./user-address.template.html'),
    ready(){  
        bus.$on('test-event', () => {console.log('Event message: ' +msg)}); 
        //doesn't output anything
        console.log(bus) //output shows vue instance with _events containing 'test-event'
    }
}  
...
<body>
    <update-user>
        <users-list></users-list>
        <edit-user>
            <user-address></user-address>
        </edit-user>
    </update-user>
</body>
...
bus.$on('test-event', () => {
  console.log('Event message: ' +msg); 
  return true;
}); 
import Vue from vue;

var bus = new Vue({});

Object.defineProperty(Vue.prototype, $bus, {
    get(){
        return this.$root.bus;
    }
});  

Vue.component('update-user', require('./components/update-user');
Vue.component('users-list', require('./components/users-list');
Vue.component('edit-user', require('./components/edit-user');
Vue.component('user-address', require('./components/user-address');

new Vue({
    el:'body',
    ready(){

    },
    data:{
       bus:bus
    }
});   
this.$bus.$emit('custom-event', {message:'This is a custom event'});  
this.$bus.$on('custom-event', event => {
    console.log(event.message);  
    //or I can assign the message to component's data property  
    this.message = event.message;  

    //if this event is intended to be handled in other components as well
    //then as we normally do we need to return true from here  
    return true;
});