初学Vue(全家桶)-第14天(vue2):消息订阅与发布实现组件间通信

初学Vue

消息订阅与发布

概述

  • 功能:
    一种组件间通信的方式,实现任意组件间通信
  • 使用步骤:

1、安装pubsub:npm i pubsub-js
2、引入:import pubsub from 'pubsub-js'
3、接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身

methods(){
    
    
	demo(data){
    
    ...}
}
...
mounted(){
    
    
	this.pid = pubsub.subscribe('xxx',this.demo) // 订阅消息
}

4、提供数据:pubsub.publish('xxx',数据),xxx是订阅名
5、使用消息订阅与发布后,最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)去取消订阅
6、需要注意的地方是消息订阅中this的指向,如果subscribe方法回调函数如果用普通函数标识,那么会因为引入了第三方的库,导致普通函数的this并不是指向组件实例对象,而是undefined

mounted(){
    
    
	pubsub.subscribe('xxx',function(){
    
    
		console.log(this) // undefined
		......
	}
	) // 订阅消息
}

所以通常要么回调函数用箭头函数实现,要么通过this调用定义在methods中的方法。

举个例子

实现School.vue和Student.vue组件之间的通信

  • 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>
  </div>
</template>

<script>
import pubsub from 'pubsub-js'
export default {
      
      
    name:"School",
    data(){
      
      
        return {
      
      
            name:"清华大学",
            address:"北京"
        }
    },
    methods:{
      
      
        demo1(){
      
      
            console.log("hello,我是School组件,我收到了来自Student组件的消息")
        },

        // 接收两个参数,第一个参数MsgName是订阅名,另一个接收到的才是数据(通常可以传对象)
        demo2(MsgName,name){
      
      
            console.log("我是School组件,我收到了来自Student组件的数据",MsgName,name); 
        }
    },
    mounted(){
      
      
        this.pid1 = pubsub.subscribe('sayHello',this.demo1) // sayHello是订阅名,不是事件和函数
        this.pid2 = pubsub.subscribe('recieveData',this.demo2) // subscribe方法有一个返回值id, 用于使用后取消订阅
    },
    beforeDestroy(){
      
      
        // 当组件销毁前销毁
        pubsub.unsubscribe(this.pid1) // 通过pid取消消息订阅
        pubsub.unsubscribe(this.pid2)
    }
}
</script>

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

<script>
import pubsub from 'pubsub-js'
export default {
      
      
    name:"Student",
    data(){
      
      
        return {
      
      
            name:"张三",
            age:21
        }
    },
    methods:{
      
      
        // 触发click事件后调用该方法
        sendMsgToSchool(){
      
      
            // 给指定订阅名发布消息
            pubsub.publish('sayHello')
        },
        sendDataToSchool(name){
      
      
            pubsub.publish('recieveData',this.name)
        }
    }
}
</script>

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

猜你喜欢

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