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

文章目录

        • 一、全局事件总线
          • 1. 什么是全局事件总线?
          • 2. 安装全局事件总线
          • 3. 使用事件总线
          • 4. 解绑事件
          • 5. 实例:实现兄弟间的组件通信(全局事件总线)
        • 二、消息订阅与发布
          • 1. 什么是消息订阅与发布?
          • 2. 使用步骤
          • 3. 实例:实现兄弟间的组件通信(消息订阅与发布)


一、全局事件总线

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>

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

二、消息订阅与发布

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>

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

你可能感兴趣的:(Vue2,&,Vue3,vue.js,javascript,前端)