Vue —— 进阶脚手架(五)(全局事件总线、消息订阅与发布)


一、全局事件总线

1. 什么是全局事件总线?

这是一种组件间通信的方式,适用于任意组件间通信。

2. 安装全局事件总线
	new Vue({
    
    
		.....
		beforeCreate() {
    
    
			Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的 vm
		}
	})
3. 使用事件总线
  1. 接收数据:A组件想接收数据,则在 A组件中给 $bus 绑定自定义事件,事件的回调留在 A组件自身。
	methods: {
    
    
		demo(data) {
    
    ....}
	},
	....
	mounted() {
    
    
		this.$bus.$on('xxx', this.demo)
	}
  1. 提供数据
	this.$bus.$emit('xxx', 数据)
4. 解绑事件

最好在 beforeDestroy 钩子中,用 $off 去解绑当前组件所用到的事件。

5. 实例:实现兄弟间的组件通信(全局事件总线)

main.js

  1. 在生命周期钩子 beforeCreate() 中安装全局事件总线
	// 引入 Vue
	import Vue from 'vue'
	// 引入 App
	import App from './App.vue'
	// 关闭 vue 的生产提示
	Vue.config.production = false
	
	//创建 vm
	new Vue({
    
    
	    el: '#app',
	    render: h => h(App),
	    beforeCreate() {
    
    
	        Vue.prototype.$bus = this //安装全局事件总线
	    }
	})

Student.vue

  1. $emit() 触发自定义事件( hello 事件)
  2. 为 School 组件提供 this.name(即张三) 数据
	<template>
	  <div class="demo">
	    <h2>学生姓名:{
    
    {
    
     name }}</h2>
	    <h2>学生性别:{
    
    {
    
     sex }}</h2>
	    <button @click="sendStudentName">把学生名给School组件</button>
	  </div>
	</template>
	
	<script>
	export default {
    
    
	  name: "StudentName",
	  data() {
    
    
	    return {
    
    
	      name: "张三",
	      sex: "男",
	    };
	  },
	  methods: {
    
    
	    sendStudentName() {
    
    
	      this.$bus.$emit("hello", this.name);
	    },
	  },
	};
	</script>

School.vue

  1. 提供数据:School 组件中给 $bus 绑定自定义事件,事件的回调留在 School 组件自身。
  2. 组件被销毁之前,在 beforeDestroy() 中进行自定义事件的解绑。
	<template>
	  <div class="demo">
	    <h2>学校名称:{
    
    {
    
     name }}</h2>
	    <h2>学校地址:{
    
    {
    
     address }}</h2>
	  </div>
	</template>
	
	<script>
	export default {
    
    
	  name: "SchoolName",
	  data() {
    
    
	    return {
    
    
	      name: "哔哩哔哩",
	      address: "中国",
	    };
	  },
	  methods:{
    
    
	      demo(data){
    
    
	        console.log("我是School组件,我收到了数据", data);
	      }
	  },
	  mounted() {
    
    
	    this.$bus.$on("hello", this.demo);
	  },
	  beforeDestroy() {
    
    
	    this.$bus.$off("hello");
	  },
	};
	</script>

App.vue

  1. 配置相关子组件的标签
	<template>
	  <div class="app">
	    <h3>{
    
    {
    
     msg }}</h3>
	    <School />
	    <student />
	  </div>
	</template>
	
	<script>
	// 引入组件
	import School from "./components/School.vue";
	import Student from "./components/Student.vue";
	export default {
    
    
	  name: "App",
	  components: {
    
     School, Student },
	  data() {
    
    
	    return {
    
    
	      msg: "你好啊",
	    };
	  },
	};
	</script>

在这里插入图片描述

二、消息订阅与发布

1. 什么是消息订阅与发布?

一种组件间通信的方式,适用于任意组件间通信。

2. 使用步骤
  1. 安装 pubsub:npm i pubsub-js
  1. 引入:import pubsub from 'pubsub-js'
  1. 接收数据:A组件想接收数据,则在 A组件中订阅消息,订阅的回调留在 A组件自身。
	methods: {
    
    
		demo(data) {
    
    ....}		
	},
	....
	mounted() {
    
    
		this.pubId = pubsub.subscribe('xxx', this.demo) //订阅消息
	}
  1. 提供数据:pubsub.publish('xxx', 数据)
  1. 最好在 beforeDestroy 钩子中,使用 PubSub.unsubscribe(pubid) 去取消订阅。
3. 实例:实现兄弟间的组件通信(消息订阅与发布)

main.js 不需要添加任何内容

App.vue 不需要做改变

Student.vue

  1. 引入 pubsub
  2. 提供订阅数据:pubsub.publish(‘xxx’)
	<template>
	  <div class="demo">
	    <h2>学生姓名:{
    
    {
    
     name }}</h2>
	    <h2>学生性别:{
    
    {
    
     sex }}</h2>
	    <button @click="sendStudentName">把学生名给School组件</button>
	  </div>
	</template>
	
	<script>
	import pubsub from 'pubsub-js'
	export default {
    
    
	  name: "StudentName",
	  data() {
    
    
	    return {
    
    
	      name: "张三",
	      sex: "男",
	    };
	  },
	  methods: {
    
    
	    sendStudentName() {
    
    
	      pubsub.publish('hello', this.name)
	    },
	  },
	};
	</script>

School.vue

  1. 引入 pubsub
  2. 接收数据:this.pubId = pubsub.subscribe('xxx', this.demo)
  3. 组件被销毁之前,在 beforeDestroy() 中取消订阅。
	<template>
	  <div class="demo">
	    <h2>学校名称:{
    
    {
    
     name }}</h2>
	    <h2>学校地址:{
    
    {
    
     address }}</h2>
	  </div>
	</template>
	
	<script>
	import pubsub from 'pubsub-js'
	export default {
    
    
	  name: "SchoolName",
	  data() {
    
    
	    return {
    
    
	      name: "哔哩哔哩",
	      address: "中国",
	    };
	  },
	  methods:{
    
    
	    demo(msgName, data) {
    
    
	      console.log('有人发布了hello消息,hello消息的回调执行了', msgName, data);
	      console.log(this);
	    }
	  },
	  mounted() {
    
    
	    this.pubId = pubsub.subscribe('hello', this.demo)
	  },
	  beforeDestroy() {
    
    
	    pubsub.unsubscribe(this.pubId)
	  },
	};
	</script>

不积跬步无以至千里 不积小流无以成江海

猜你喜欢

转载自blog.csdn.net/qq_45902692/article/details/124801519