初学Vue(全家同)-第13天(vue2):全局事件总线实现组件间通信

初学Vue

全局事件总线

1、功能

实现任意组件间通信

2、图示

拿兄弟组件之间的通信来举例,Son2传递数据给Son1,如下:
在这里插入图片描述

分析如下:
在Son1中自定义一个事件并绑定回调函数(@demo=“function”),将这个事件(demo)交给全局事件总线,Son2利用全局事件总线,触发demo事件,随即demo事件调用回调函数。

很好理解,就是全局事件总线是个工具人,别人叫它干什么就干什么,它可以让所有的组件都能够使用上面的事件,那么问题来了,它位于什么上?vueComponent.prototype?不是。所有的组件都是通过vueComponennt构造函数创建出来的,但每次调用Vue.extend时返回的都是一个新的VueComponent,不好管理。
注意,有这么一个内置关系vueComponent.prototype._proto_===Vue.prototype,用于让组件实例对象vc可以访问Vue原型上的属性和方法,由此知道可以将这个全局事件总线放在Vue的原型对象上。

通常用$bus来表示全局事件总线。

3、使用步骤

1、安装事件总线

new Vue({
    
    
	beforeCreate(){
    
    
		Vue.prototype.$bus = this
		// this指的就是当前实例对象vm,也就是说$bus这个事件总线就是vm	
	}
});

2、使用事件总线
(1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

methods(){
    
    
	demo(data){
    
    ......}
}
....

mounted(){
    
    
	this.$bus.$on('xxx',this.demo)
}

(2)提供数据:this.$bus.$emit('xxx',数据)

(3)并且最好在new Vue()中使用beforeDestroy钩子,用$off去解绑当前组件中所用到的事件。

4、使用案例

有两个兄弟组件School.vue和Student.vue,让Student组件往School组件上传递数据。

  • main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
    
    
  render: h => h(App),
  // 安装全局事件总线
  beforeCreate(){
    
    
    Vue.prototype.$bus=this // this指的是当前对象vm
  }
}).$mount('#app')

  • App.vue
<template>
  <div id="app">
    <School></School>
    <Student></Student>
  </div>
</template>

<script>
import School from "./components/School.vue"
import Student from "./components/Student.vue"

export default {
      
      
  name:"App",
  components:{
      
      School,Student},
}
</script>

<style>
  #app{
      
      
    background-color: grey;
  }
</style>
  • School.vue
<template>
  <div class="school">
      <h3>学校名称:{
   
   {name}}</h3>
      <h3>学校地址{
   
   {address}}</h3>
      <!-- <button>点我把数据传给Student组件</button> -->
  </div>
</template>

<script>
export default {
      
      
    name:"School",
    data(){
      
      
        return {
      
      
            name:"清华大学",
            address:"北京"
        }
    },
    mounted(){
      
      
        // 将School组件上的event1事件通过$on放到全局事件总线$bus上
        this.$bus.$on("event1",(data)=>{
      
      
            console.log("我是School组件,收到了数据",data);
        // 回调要使用箭头函数的形式,这里的this指向函数绑定的对象,这里也就是School组件的vc
        })
    }
}
</script>

<style>
    .school{
      
      
        background-color: lightgreen;
    }
</style>
  • Student.vue
<template>
  <div class="student">
      <h3>学生姓名:{
   
   {name}}</h3>
      <h3>学生年龄:{
   
   {age}}</h3>
      <button @click="sendMsgToSchool">点我把数据传给School组件</button>
  </div>
</template>

<script>
export default {
      
      
    name:"Student",
    data(){
      
      
        return {
      
      
            name:"张三",
            age:21
        }
    },
    
    methods:{
      
      
        // 触发click事件后调用该方法
        sendMsgToSchool(){
      
      
            // 通过this使用全局事件总线$bus,再通过$emit触发总线上指定的事件
            this.$bus.$emit("event1",this.name);
        }
    }
}
</script>

<style>
    .student{
      
      
        background-color: pink;
    }
</style>

5、页面效果展示

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lalala_dxf/article/details/125165946