• Vue (十) --------- 全局事件总线、消息订阅与发布



    一、全局事件总线

    全局事件总线,是组件间的一种通信方式,适用于任何组件间通信

    首先我们在 main.js 中,安装全局事件总线

    import Vue from 'vue';  
    import App from './App.vue';
     
    Vue.config.productionTip = false;
     
    new Vue({
        el:"#app",
        render: h => h(App),
        beforeCreate(){ 
          Vue.prototype.$bus = this;
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    $bus定义在Vue.prototype,因此$bus对所有组件可见,即所有组件可通过this.$bus访问。

    $bus被赋值为this,即vm实例,因此$bus拥有vm实例上的所有属性和方法,如$emit、$on、$off,所有组件实例对象的原型对象的原型对象就是 Vue 的原型对象。

    使用事件总线

    $bus.$on,监听事件。Employee 组件中定义了监听事件,监听 demo 事件;

    $bus.$emit,触发事件。Company 组件中定义了触发事件,点击按钮执行 sendMessage 回调,该回调将触发 demo 事件。

    $off(eventName),解绑自定义事件监听,最好在 beforeDestory 钩子函数中解绑

    $once(eventName, listener),绑定事件监听, 但只能处理一次。

    接收数据:

    methods(){
        demo(data){......}    //提前配置好 demo 函数
    }
    mounted(){
        this.$bus.$on('xxx',this.demo)   //绑定自定事件时,回调要么配置在 methods中,要么用箭头函数,否则 this 指向会出问题
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    指定事件总线对象

    new Vue({
       beforeCreate () { // 尽量早的执行挂载全局事件总线对象的操作
       Vue.prototype.$globalEventBus = this
    },}).$mount('#root')
    
    • 1
    • 2
    • 3
    • 4

    绑定事件

    this.$globalEventBus.$on('deleteTodo', this.deleteTodo)

    分发事件

    this.$globalEventBus.$emit('deleteTodo', this.index)

    解绑事件

    this.$globalEventBus.$off('deleteTodo')

    二、消息订阅与发布

    一种组件间通信的方式,适用于任意组件间通信。其思想类似于全局事件总线,事件总线只适用于平级组件间通信。

    它包含以下操作:

    (1) 订阅消息 --对应绑定事件监听
    (2) 发布消息 --分发事件
    (3) 取消消息订阅 --解绑事件监听

    使用消息我们需要引入一个消息订阅与发布的第三方实现库: PubSubJS

    使用 PubSubJS

    在线文档: https://github.com/mroderick/PubSubJS

    使用步骤:

    • 下载 npm install -S pubsub-js
    • 引入 import PubSub from 'pubsub-js'
    • 订阅消息 PubSub.subscribe(‘msgName’, functon(msgName, data){ })
    • 发布消息, 触发订阅的回调函数调用 PubSub.publish(‘msgName’, data)
    • 取消消息的订阅 PubSub.unsubscribe(token)

    举例:

    Student.vue

    <template>
    	<div class="student">
    		<h2>学生姓名:{{name}}</h2>
    		<h2>学生性别:{{sex}}</h2>
    		<button @click="sendStudentName">把学生名给School组件</button>
    	</div>
    </template>
    
    <script>
    	import pubsub from 'pubsub-js'
    	export default {
    		name:'Student',
    		data() {
    			return {
    				name:'张三',
    				sex:'男',
    			}
    		},
    		mounted() {
    			// console.log('Student',this.x)
    		},
    		methods: {
    			sendStudentName(){
    				// this.$bus.$emit('hello',this.name)
    				pubsub.publish('hello',666)
    			}
    		},
    	}
    </script>
    
    <style lang="less" scoped>
    	.student{
    		background-color: pink;
    		padding: 5px;
    		margin-top: 30px;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    School.vue

    <template>
    	<div class="school">
    		<h2>学校名称:{{name}}</h2>
    		<h2>学校地址:{{address}}</h2>
    	</div>
    </template>
    
    <script>
    	import pubsub from 'pubsub-js'
    	export default {
    		name:'School',
    		data() {
    			return {
    				name:'qdu',
    				address:'青岛',
    			}
    		},
    		mounted() {
    			// console.log('School',this)
    			/* this.$bus.$on('hello',(data)=>{
    				console.log('我是School组件,收到了数据',data)
    			}) */
    			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
    				console.log(this)
    				// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
    			})
    		},
    		beforeDestroy() {
    			// this.$bus.$off('hello')
    			pubsub.unsubscribe(this.pubId)
    		},
    	}
    </script>
    
    <style scoped>
    	.school{
    		background-color: skyblue;
    		padding: 5px;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    路由过滤与引入
    (原创)【B4A】一步一步入门05:控件、公有属性、水平锚定、垂直锚定(控件篇01)
    深度剖析Java的volatile实现原理,再也不怕面试官问了
    量子力学与哲学的交叉:现实性,自由意志和意识
    OpenCV读取tensorflow神经网络模型:SavedModel格式转为frozen graph的方法
    P1554 梦中的统计--------洛谷 / 题目列表 / 题目详情
    Bearly:基于人工智能的AI写作文章生成工具
    后端编写Swagger接口管理文档
    Javascript最全面试题
    Android开发基础——Kotlin:高阶函数
  • 原文地址:https://blog.csdn.net/m0_51111980/article/details/125521227