一、全局事件总线
1. 什么是全局事件总线?
这是一种组件间通信的方式,适用于任意组件间通信。
2. 安装全局事件总线
new Vue({ ..... beforeCreate() { Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的 vm } })
3. 使用事件总线
- 接收数据:A组件想接收数据,则在 A组件中给 $bus 绑定自定义事件,事件的回调留在 A组件自身。
methods: { demo(data) {....} }, .... mounted() { this.$bus.$on('xxx', this.demo) }
- 提供数据
this.$bus.$emit('xxx', 数据)
4. 解绑事件
最好在 beforeDestroy 钩子中,用 $off 去解绑当前组件所用到的事件。
5. 实例:实现兄弟间的组件通信(全局事件总线)
main.js
- 在生命周期钩子 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
- $emit() 触发自定义事件( hello 事件)
- 为 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
- 提供数据:School 组件中给 $bus 绑定自定义事件,事件的回调留在 School 组件自身。
- 组件被销毁之前,在 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
- 配置相关子组件的标签
<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. 使用步骤
- 安装 pubsub:npm i pubsub-js
- 引入:import pubsub from 'pubsub-js'
- 接收数据:A组件想接收数据,则在 A组件中订阅消息,订阅的回调留在 A组件自身。
methods: { demo(data) {....} }, .... mounted() { this.pubId = pubsub.subscribe('xxx', this.demo) //订阅消息 }
提供数据:pubsub.publish('xxx', 数据)
最好在 beforeDestroy 钩子中,使用 PubSub.unsubscribe(pubid) 去取消订阅。
3. 实例:实现兄弟间的组件通信(消息订阅与发布)
main.js 不需要添加任何内容
App.vue 不需要做改变
Student.vue
- 引入 pubsub
- 提供订阅数据: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
- 引入 pubsub
- 接收数据:this.pubId = pubsub.subscribe('xxx', this.demo)
- 组件被销毁之前,在 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>
不积跬步无以至千里 不积小流无以成江海