VU 非父子组件通信

作者:高玉涵
时间:2022.7.28 08:55
博客:blog.csdn.net/cg_i

一、组件通信

 组件关系可分为父子组件通信(通过 props 传递数据)、兄弟组件通信、跨级组件通信。这里我主要介绍跨级组件通信的方法。

在这里插入图片描述

1.1 非父子组件通信

 非父子组件一般有两种,兄弟组件和跨多级组件。在 Vue.js 2.x 中,使用一个空的 Vue 实例作为中央事件总线(bus),也就是一个中价。为了更形象地了解它,我们举一个生活中的例子。
 比如你需要租房子,你可能会找户产中介来登记你的需求,然后中介把你的信息发给满足要求的出租者,出租者再把报价和看房时间告诉中介,由中介再转达给你,整个过程中,买家和卖家并没有任何交流,都是通过中间人来传话的。
 或者你最近可能要换房子,你会找房产中介登记你的信息,订阅与你找户需求相关的资讯,一旦有符合你的房子出现时,中介会通知你,并传达你房子的具体信息。
 这两个例子中,你和出租者担任的就是两个跨级的组件,而房产中介就是这个中央事件总线(bus)。比如下面的示例代码:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <title>跨组件通信</title>
    </head>
    <body>
        <div id="app">
            {{ message }}
            <component-a></component-a>
        </div>

        <script src="../vue.js"></script>
        <script>
           var bus = new Vue();

           Vue.component('component-a',{
                template: '<button @click="handleEvent">传递事件</button>',
                methods:{
                    handleEvent: function (){
                        bus.$emit('on-message', '来自组件 component-a 的内容');
                    }
                }
            });

            var app = new Vue ({
                el: '#app',
                data: {
                    message: ''
                },
                mounted: function (){
                    var _this = this;
                    // 在实例初始化时,监听来自 bus 实例的事件
                    bus.$on('on-message', function (msg){
                        _this.message = msg;
                    });
                }
            });
        </script>
    </body>
</html>

 首先创建一个名为 bus 的空 Vue 实例,里面没有任何内容:然后全局定义了组件 component-a;最后创建 Vue 实例 app,在 app 初始化时,也就是在生命周期 mounted 钩子函数里监听了来自 bus 的事件 on-message,而在组件 component-a 中,点击按钮会通过 bus 把事件 on-message 发出去,此时 app 就会接收到来自 bus 的事件,进而回调里完成自己的业务逻辑。
 这种方法巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级,而且 Vue 1.x 和 Vue 2.x 都适用。如果深入使用,可以扩展 bus 实例,给它添加 data、methods、computed 等选项,这些都是可以公用的,在业务中,尤其是协同开发时非常有用,因为经常需要共享一些通用的信息,比如用户登录的昵称、性别、邮箱等,还有用户的授权 token 等。只需在初始化时 bus 获取一次,任何时间、任何组件就可以从中直接使用了。

在这里插入图片描述

二、补充知识:自定义事件

 当子组件需要向父组件传递数据时,就要用到自定义事件。指令 v-on 除了监听 DOM 事件外,还可以用于组件之间的自定义事件。 Vue 中子组件用 $emit() 来触发事件,父组件用 $on() 来监听子组件的事件。父组件也可以直接在子组件的自定义标签上使用 v-on 来监听子组件触发的自定义事件。示例代码如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <title>自定义事件</title>
    </head>
    <body>
        <div id="app">
           <p>总数:{{ total }}</p>
           <my-component
            @increase="handleGetTotal"
            @reduce="handleGetTotal"></my-component>
        </div>

        <script src="../vue.js"></script>
        <script>
           Vue.component('my-component',{
                template: '\
                <div>\
                    <button @click="handleIncrease">+1</button>\
                    <button @click="handleReduce">-1</button>\
                </div>',
                data: function () {
                    return {
                        counter:0
                    }
                },
                methods:{
                    handleIncrease: function (){
                        this.counter++;
                        this.$emit('increase', this.counter);
                    },
                    handleReduce: function (){
                        this.counter--;
                        this.$emit('reduce', this.counter);
                    }
                }
            });

            var app = new Vue ({
                el: '#app',
                data: {
                    total: ''
                },
                methods:{
                    handleGetTotal:function (total){
                        this.total = total;
                    }
                }
            });
        </script>
    </body>
</html>

在这里插入图片描述

 上面示例中,子组件有两个按钮,分别实现加 1 和减 1 的效果,在改变组件的 data “counter” 后,通过 $emit() 再把它传递给父组件,父组件用 v-on:increase 和 v-on:reduce(示例使用的是语法糖)。$emit() 方法的第一个参数是自定义事件的名称,例如示例的 increase 和 reduce 后面的参数都是要传递的数据,可以不填或填写多个。

 除了用 v-on 在组件上监听自定义事件外,也可以监听 DOM 事件,这时可以用 .native 修饰符表示监听的是一个原生事件,监听的是该组件的根元素,示例代码如下:

<my-component v-on:click.native="handleClick"></my-component>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值