美文网首页
Vue中非父组件通信(中央事件总线)

Vue中非父组件通信(中央事件总线)

作者: ChasenGao | 来源:发表于2018-05-16 17:25 被阅读61次

全局注册的组件:

    <body>
        <div id="app">
            <one></one>
            <two></two>
        </div>
        <script type="text/javascript">
            var bus = new Vue();
            Vue.component('one', {
                template: '<p @click="click">我是一个组件</p>',
                props: {
                    ms: {
                        type: Number,
                        default: 0
                    }
                },
                methods: {
                    click() {
                        this.ms++;
                        console.log(this.ms)
                        bus.$emit('setmsg', this.ms)
                    }
                }
            });
            Vue.component('two', {
                template: '<p>我是另一个组件{{msg}}</p>',
                props: {
                    msg: {
                        type: Number
                    }
                },
                created() {
                        var _this = this;
                        bus.$on('setmsg', function(ms) {
                            _this.msg = ms;
                        })
                    }
            })
            var app = new Vue({
                el: "#app"
            })
        </script>
    </body>

1、新建一个名为bus的vue实例,作为通信的媒介。
2、新建两个组件,one 和 two。
3、one组件中,添加点击事件,每次点击时,通过$emit把值发给bus,用白话来说,就是告诉bus,我这有个值this.ms先给你,如果谁需要接收这个值,需要用setmsg这个名称来接收。

4、组件two中,添加一个在组件创建时变执行的方法,关于什么时候执行方法,请了解“vue生命周期钩子”相关内容。

5、方法中,通过$on来告诉bus,我想接收刚才给你的值,$on的第二个参数function的参数ms,是任意命名的,因为无论是什么名字,他都代表刚才bus接收到的this.ms。

6、在$on之前,需要var _this = this',这么做是为了让this指向自己,如果不这么写,那么在$on中使用this.msg = ms,那么this指向的就是bus而不是接收数值的组件了。



局部注册的组件:
<body>
    <div id="app1">
        <one></one>
    </div>
    <div id="app2">
        <two></two>
    </div>
    <script type="text/javascript">
        var hub = new Vue()
        var vm1 = new Vue({
            el:'#app1',
            components:{
                one:{
                    template:'<p @click="click">我是一个组件</p>',
                    props:{
                        ms:{
                            type:Number,
                            default:0
                        }
                    },
                    methods:{
                        click(){
                            this.ms++;
                            console.log(this.ms)
                            hub.$emit('setmsg',this.ms)
                        }
                    }
                }
            }
        })
        
        var vm2 = new Vue({
            el:'#app2',
            components:{
                two:{
                    template:'<p>我是另一个组件{{ms2}}</p>',
                    props:{
                        ms2:{
                            type:Number
                        }
                    },
                    created(){
                        var _this = this;
//                      console.log(this)
                        hub.$on('setmsg',function(ms){
                            _this.ms2 = ms;
//                          console.log(this)
                        })
                    }
                }
            }
        })
    </script>
</body>

实现方式几乎一样,只不过两个组件都是局部注册的,需要在不同的vue实例中显示,但是不影响互相通信。

我在本例中,没有把媒介命名为bus而是Hub,意思是媒介的命名是随意的。



点击事件触发通信
可能你还不太了解生命周期钩子,所以我修改了一下实例2中的代码,使用点击事件来触发。
代码如下:
<body>
    <div id="app1">
        <one></one>
    </div>
    <div id="app2">
        <two></two>
    </div>
    <script type="text/javascript">
        var hub = new Vue()
        var vm1 = new Vue({
            el:'#app1',
            components:{
                one:{
                    template:'<p @click="click">我是一个组件</p>',
                    props:{
                        ms:{
                            type:Number,
                            default:0
                        }
                    },
                    methods:{
                        click(){
                            this.ms++;
                            console.log(this.ms)
                            hub.$emit('setmsg',this.ms)
                        }
                    }
                }
            }
        })
        
        var vm2 = new Vue({
            el:'#app2',
            components:{
                two:{
                    template:'<p @click="click">我是另一个组件{{ms2}}</p>',
                    props:{
                        ms2:{
                            type:Number
                        }
                    },
                    methods:{
                        click(){
                            var _this= this;
                            hub.$on('setmsg',function(ms){
                                _this.ms2 = ms;
                            })
                        }
                    }
                }
            }
        })
    </script>
</body>

我把数据接收放到了methods的方法中,运行后,直接点击组件1 无效果。
刷新页面,先点击组件2,再点击组件1,效果实现,因为传递数据是通过点击事件来启动的。

相关文章

  • Vue中非父组件通信(中央事件总线)

    全局注册的组件: 1、新建一个名为bus的vue实例,作为通信的媒介。2、新建两个组件,one 和 two。3、o...

  • vue组件通信,中央事件总线

    vue 组件通信分为父组件与子组件通信、子组件与父组件通信、非父子关系组件通信三种 第一种大家都知道用props,...

  • 非父子组件间的通信

    非父子组件间的通信,可以通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件

  • Vue组件通信

    父组件传值子组件 子组件传值父组件 非父子组件通信 发布订阅模式 / 总线模式 我们使用一个空的Vue实例作为总线...

  • eventBus封装

    中央事件总线eventBus的实质就是创建一个vue实例,通过一个空的vue实例作为桥梁实现vue组件间的通信。它...

  • 2019-02-14 vue组件基础篇3

    非父子组件通信 1.使用一个空的Vue实例作为中央事件总线(bus)2.bus.$emit('key', 'tex...

  • 非父子组件间通信

    上一篇:父子组件间单向数据流的解决办法 非父子组件之间的通信,可以通过一个空的 Vue 实例作为中央事件总线(事件...

  • vue事件总线EventBus

    vue组件有父子组件通信:props兄弟组件通信:可以使用vuex,还可以使用事件总线eventBus 使用方法:...

  • 22.Vue全局事件总线(GlobalEventBus)

    一种组件间通信的方式,适用于任意组件间通信 安装全局事件总线:new Vue({ ...... beforeCre...

  • Vue父子组件间通信(数据传递)

    父---props--->子子---props/自定义事件/全局事件总线/消息订阅与发布--->父任意组件间通信:...

网友评论

      本文标题:Vue中非父组件通信(中央事件总线)

      本文链接:https://www.haomeiwen.com/subject/htxmdftx.html