1.常见的组件通信方式

        pros:父组件传子组件

        自定义事件:子组件传父组件

        vuex:均可实现

        插槽:父组件传子组件

        pubsub-js:均可实现(较少用)

        $bus全局事件总线:均可实现

2.事件总线的介绍

        如果咱们的应用程序不需要类似Vuex这样的库来处理组件之间的数据通信,就可以考虑Vue中的事件总线来实现。它相当于一个全局的仓库,任何组件都可以去这个仓库里获取事件,它就类似沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行的通知其他组件来进行通信。

3.事件总线原理

        因为所有组件对象都能看到 Vue 原型对象上的属性和方法,所以我们可以在Vue的原型对象上通过设定一个bus对象,Vue.prototype.bus = new Vue(),此时所有的组件对象都能看到bus属性对象。

        同时由于Vue 原型对象上包含以下事件处理的方法:
        $on(eventName, listener): 绑定自定义事件监听
        $emit(eventName, data): 分发自定义事件
        $off(eventName): 解绑自定义事件监听
        $once(eventName, listener): 绑定事件监听, 但只能处理一次

        所以我们可以通过组件调用Vue 原型对象中属性对象bus的方法来实现通信。

4.总线的实现

    4.1定义事件总线对象

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

//给Vue绑定属性
Vue.prototype.xyz=100;
// Vue.prototype.$EventBus=vm

new Vue({
  beforeCreate(){
  //安装事件总线
  Vue.prototype.abc=900;
  Vue.prototype.$EventBus=this
 },
  render: h => h(App),
}).$mount('#app')

  4.2  向总线发送事件

            语法:this.$EventBus.$emit(发送的事件名,传递的参数)

<!--  -->
<template>
  <div id="demo01">
    <h1>Demo01组件</h1>
    <h2>从Demo02接受的收据:{{msg}}</h2>
    <button @click="fasong">发送数据给Demo02</button>
  </div>
</template>

<script>
export default {
  name: "Demo01",
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    test01 (data) {
      console.log(data);
      this.msg = data
    },
    fasong () {
      this.$EventBus.$emit("send", "我是Demo01页面");
    }
  },
  mounted () {
    // console.log(this);
    // 2.接受全局的haha事件
    this.$EventBus.$on('haha', this.test01)
  }
}
</script>
<style scoped>
#demo01 {
  background-color: red;
  padding: 20px;
  margin-bottom: 20px;
}
</style>

 4.3接收总线事件

       语法:this.$EventBus.$on(监听的事件名, 回调函数)

<!--  -->
<template>
  <div id="demo02">
    <h1>Demo02组件</h1>
    <button @click="sendData">发送事件给Demo01</button>
    <h2>从Demo01接受的收据:{{msg}}</h2>
  </div>
</template>

<script>
export default {
  name: "Demo02",
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    sendData () {
      // 触发全局的haha事件
      this.$EventBus.$emit("haha", '老王')
    },
    display (data) {
      console.log(data);
      this.msg = data
    }
  },
  mounted () {
    // console.log(this.abc);
    console.log(this.$EventBus);
    this.$EventBus.$on("send", this.display)
  }
}
</script>
<style scoped>
#demo02 {
  background-color: blue;
  padding: 20px;
}
</style>

 4.3总线事件解绑

        语法:this.$EventBus.$off(要移除事件名)

        在组件离开,也就是被销毁前,要将该监听事件给移除,以免下次再重复创建监听。

  beforeDestory () {
    //移除事件监听send
    this.$EventBus.off("send")
  }

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐