Vue之全局事件总线$bus

全局事件总线:可以实现任意组件间通信

关于VueComponent:

  1. school组件 本质是一个名为 VueComponent 的构造函数, 且不是程序员定义的,是 Vue.extend 生成的,即 Vue.extend({ })的返回值。
  2. 我们只需要写<school/><schoo1></school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options )
  3. 特别注意:每次调用 Vue.extend 返回的都是一个全新的 VueComponent。
  4. 关于this指向:
    (1) 组件配置中:data函数、methods 中的函数、watch中的函数、computed中的函数它们的this均是【VueComponent实例对象】。
    (2) new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是【Vue实例对象】。
  5. VueComponent 的实例对象,以后简称 vc (也可称之为:组件实例对象)。
    Vue 的实例对象,以后简称 vm。

一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
为什么要有这个关系:让组件实例对象(vc)可以访问到Vue原型上的属性、方法

所以:

main.js

import Vue from 'vue'
import App from './App.vue'

// 所以将x放在Vue的原型对象上,其他组件都可以访问了
Vue.prototype.x = {a:1, b:2}

// 创建vm
new Vue({
	el: '#app',
	render: h = h(App),
})

School.vue

<script>
	export default {
		name: 'School',
		mounted() {
			console.log(this.x)   // {a:1, b:2}
	}

main.js

import Vue from 'vue'
import App from './App.vue'

// 创建组件
const Demo = Vue.extend({})
// 创建组件的实例对象(即<school/>
const d = new Demo()

Vue.prototype.x = d

// 创建vm
new Vue({
	el: '#app',
	render: h = h(App),
})

接收数据: School组件想接收数据,则在School组件中给$bus绑定自定义事件,事件的回调留在School组件自身。

School.vue

<script>
	export default {
		name: 'School',
		mounted() {
			this.x.$on('hello', (data) => {
				console.log('哈哈', data)  // 哈哈张三
			})
		}
	}

提供数据: Student组件触发事件

Student.vue

<button @click="sendStudentName">把学生名给School组件</button>
......
export default {
	name: 'Student',
	data() {
		return {
			name: '张三',
		}
	},
	methods: {
		sendStudentName() {
			this.x.$emit('hello',this.name)
		}

最终:

安装全局事件总线:

main.js

import Vue from 'vue'
import App from './App.vue'

// 创建vm
new Vue({
	el: '#app',
	render: h = h(App),
	// 
	beforeCreate() {
		// 安装全局事件总线
		// Vue.prototype.x = this
		// x一般命名为$bus  (bus有个翻译是总线的意思)
		Vue.prototype.$bus = this
		// 在Vue的原型对象上绑定$bus指向vm,this指向vm
})

接收数据: School组件想接收数据,则在School组件中给$bus绑定自定义事件,事件的回调留在School组件自身。

School.vue

<script>
	export default {
		name: 'School',
		mounted() {
			// 组件可沿着原型链找到$bus
			this.$bus.$on('hello', (data) => {
				console.log('哈哈', data)  // 哈哈张三
			})
		}
	}

提供数据: 触发事件:

Student.vue

<button @click="sendStudentName">把学生名给School组件</button>
......
export default {
	name: 'Student',
	data() {
		return {
			name: '张三',
		}
	},
	methods: {
		sendStudentName() {
			this.$bus.$emit('hello',this.name)
		}

解绑事件: 因为$bus绑定了很多组件的自定义事件,用完自定义事件后如果不解绑,那这个是多余的事件

School.vue

<script>
	export default {
		name: 'School',
		mounted() {
			this.$bus.$on('hello', (data) => {
				console.log('哈哈', data)  // 哈哈张三
			})
		},
		beforeDestroy() {
			this.$bus.$off('hello')
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欢莱

为您解决问题,此项目我成功完成

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值