前端vue入门(纯代码)11

这篇具有很好参考价值的文章主要介绍了前端vue入门(纯代码)11。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【11.全局事件总线(Global Event Bus)】

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

【原理图】

前端vue入门(纯代码)11

  • 结合上图,假若C组件想要传递数据给A组件,那么,就通过全局事件总线在A组件中绑定【$on】一个自定义事件demo,并界定一个参数来接收传递的数据,同样在C组件中,就需要通过全局事件总线对自定义事件demo进行触发【$emit】,并传递参数,这样就实现了任意组件之间的通信。

  • 简单理解,全局事件总线其实就是一个中间介质,组件间的相互通信借助于这个中间介质,通过这个中间转换介质,从而完成数据的传递与接收,实现组件间的相互通信。

  • 全局事件总线是一个独立存在的部分,要想实现组件间的相互通信,又是自定义事件,那就要满足两个条件:

    【1】. 所有的组件都能访问到全局事件总线【X总线】

    【2】. 可以调用$on【绑定】,$off【解绑】,$emit【触发事件】


全局事件总线应该安装在哪里呢?

  • 安装全局事件总线前需要考虑:如果要所有组件对象【vm,vc】都能够获取到事件总线
  • 从下图可以看出,当组件实例化对象vc获取数据时,会首先找到组件原型对象,如果该组件实例对象中没有此数据,那么就找到Vue的原型对象,Vue的原型对象只有一个,所有组件都能够获取到它的数据,所以事件总线要安装到Vue的原型对象上

前端vue入门(纯代码)11

结合组件的内置关系:

VueComponent.prototype.__proto__ === Vue.prototype【Vue的原型对象】

这个关系在作用就在于可以让 组件实例对象(vc,vm) 可以访问到Vue原型对象【Vue.prototype】上的属性和方法

  • 回顾知识:关于VueComponent:

    1.A、B、C子组件本质上是一个名为VueComponent的构造函数,且不是程序员定义的,是调用Vue.extend()生成的

    2.只需要写<A/>或<A></A>,Vue解析时会帮我创建A组件的实例对象,

    3.每次调用Vue.extend,返回的都是一个全新的VueComponent

  • 1. 由于是在入口文件main.js中引入的Vue,所以事件总线需要配置到main.js当中

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
  // 生命周期钩子beforeCreate中模板未解析,且this是vm
  beforeCreate() {
		Vue.prototype.$bus = this  //安装全局事件总线$bus
	}
})
  • 为什么要在Vue实例对象中采用生命周期钩子beforeCreate安装事件总线?
    • 由生命周期beforeCreate此时只是完成了初始化工作,创建了Vue实例对象,但是模板并没有解析,数据代理并没有运转。
  • 2. 接下来,我们就要对想要接收到数据的组件进行自定义事件的绑定,简单来说就是,谁【比如:A】要接收数据,自定义事件就绑定在谁【比如:A】身上 【$on()里面要是用箭头函数】
  • 绑定全局事件总线

此处若用的是箭头函数,不是普通函数,那么函数里的this指向【vc】不会有问题。

mounted(){
  // 绑定自定义事件
  //此处若用的是普通函数,不是箭头函数,那么函数里的this指向会有问题。
  this.$bus.$on('自定义事件名', (接收参数)=>{
    console.log('我是TestB组件,收到了数据', 接收参数);
    console.log('School组件里的this', this);  //vc
  })
}

此处若用的是普通函数,不是箭头函数,那么函数里的this指向【vm】会有问题。

mounted(){
  // 绑定自定义事件
  //此处若用的是普通函数,不是箭头函数,那么函数里的this指向会有问题。
  this.$bus.$on('自定义事件名',function (接收参数){
    console.log('我是TestB组件,收到了数据', 接收参数);
    console.log('School组件里的this', this);  //vm
	console.log('this.$bus', this.$bus);  //vm
  })
}
  • 3. 最后一步,全局事件总线的触发,事件的触发是在发送数据的组件中完成的,简单来说,谁【比如:B】是数据的发送者,谁【比如:B】就来触发事件
  • 触发全局事件总线
 methods:{
  // 触发事件,事件名不能重复
  触发事件方法名(){
    this.$bus.$emit('自定义事件名', 传递参数);
  }
},
  • 4. 在得到数据之后,解绑事件,提高性能,在beforedestroy生命周期钩子中,用$off解绑当前组件所用到的数据
  • 解绑自定义事件
// 销毁对应自定义事件
beforeDestroy(){
  this.$bus.$off('自定义事件名')
}

完整代码:

School.vue组件

<template>
	<div class="school">
		<h1>School组件</h1>
		<!-- 给子组件的实例对象VC绑定了事件getName,该事件触发会调用函数getStudentName -->
		<h2>兄弟组件Student传过来的name:{{ StudentName }}</h2>
		<h2>兄弟组件Student传过来的age:{{ StudentAge }}</h2>
	</div>
</template>

<script>
export default {
	name: 'School',
	data() {
		return {
			StudentName: '',
			StudentAge: '',
		};
	},
	mounted() {
		// 绑定自定义事件haha
		this.$bus.$on('haha', (...params) => {
			console.log('School组件里的', this);
			this.StudentName = params[0];
			this.StudentAge = params[1];
			console.log('我是School组件,收到了数据', params);
		});
	},
  // 销毁对应自定义事件
	beforeDestroy() {
    // 解绑自定义事件
    this.$bus.$off('haha')
  },
};
</script>

<style scoped>
.school {
	background-color: rgb(73, 192, 150);
}
</style>

  • ...params:可以以数组的形式接收多个参数。

Student.vue组件

<template>
	<div class="student">
    <h1>Student组件信息</h1>
		<h2>学生姓名:{{ name }}</h2>
		<h2>学生性别:{{ sex }}</h2>
		<h2>学生年龄:{{ age }}</h2>
		<h2>学生成绩:{{ score }}</h2>
		<button class="haha" @click="sendStudentlName">
      <h2>点击此处给兄弟组件School传值</h2></button>
	</div>
</template>

<script>
export default {
	name: 'Student',
	data() {
		return {
			name: '何大春',
			sex: '男',
			age: '22',
			score: '88',
		};
	},
	methods: {
    sendStudentlName(){
      console.log("Student组件里的",this.name);
      // 传给School组件两个参数
      this.$bus.$emit('haha',this.name,this.age)
    }
	},
};
</script>

<style lang="less" scoped>
.student {
	background-color: tomato;
	padding: 50px;
	margin-top: 50px;
	margin-left: 50px;
	width: 300px;
	height: 350px;
}
.h2 {
  padding: 5px;
  margin: 5px 5px 5px 5px;
}
.haha {
  background-color: rgb(211, 233, 130);
}
</style>

结果展示:

前端vue入门(纯代码)11

补充知识点:

问题1:“全局事件总线”需要哪些特点?

  • 1)被所有组件(vc、vm)能够看得见
  • 2)能够调用$on、$emit、$off

问题2:“Vue原型对象----Vue.prototype上面的所有属性和方法是给谁用的?

  • 是给所有的vm和vc使用的

问题3:为什么定义“全局事件总线”要放在main.js文件中?

  • 因为哪里引入Vue,哪里才会去定义“全局事件总线”

问题4:“为什么定义“全局事件总线”要放在beforeCreate的钩子函数中?

  • 1)beforeCreate钩子函数里this指代new出来的vm

  • 2)在beforeCreate钩子函数里模板还没解析,数据监测和数据代理也还没完成呢。也就是说借助这个beforeCreate钩子函数你把想做的事儿做好了,原型上该放的放好了,随后模板开始解析,等组件执行的时候你该放的都放好了,后续才都不会产生影响。

问题5:如何避免在使用“全局事件总线”时自定义函数名重名使用问题?比如组件1使用自定义函数名叫demo,那组件2不全文搜索也使用了自定义函数名也叫demo,这就混了

  • 真实项目中src目录下创建一个config文件夹,里面创建个constants常量文件,里面用来定义要使用的自定义函数名,方便别人查看并避免重名问题。

问题6:“为什么要在组件销毁之前,把“全局事件总线”中定义的自定义事件函数解绑?那“知识点组件自定义事件”中咋没说解绑的事儿呢?

  • “组件自定义事件”中,组件销毁了== vc销毁了,vc销毁了自定义事件也就销毁了,而“全局事件总线”中定义的自定义事件是一直存在的,哪怕使用组件销毁了,但是Vue实例定义的“全局事件总线”中还是会存在自定义事件,所以需要在组件销毁之前进行解绑。

注意7:销毁“全局事件总线”中定义的自定义事件请放在beforeDestroy()钩子中

注意8:子组件中使用“全局事件总线”时this.$bus.$on()中回调配置要使用箭头函数,不要使用普通函数,普通函数中this指代vue实例,而箭头函数中this才指代vc,因为最终要在school组件上接收平行组件发过来的消息,所以要使用vc,而不是要使用vue实例,因为vue实例不是我们最终要的。

mounted(){
  // 绑定自定义事件
  this.$bus.$on('自定义事件名', (接收参数)=>{
    console.log('我是TestB组件,收到了数据', 接收参数);
  })
},
	mounted() {
		// 绑定自定义事件haha
		this.$bus.$on('haha', (...params) => {
			console.log('School组件里的', this); //this = vc
			this.StudentName = params[0];
			this.StudentAge = params[1];
			console.log('我是School组件,收到了数据', params);
		});
	},
总结:

全局事件总线实现了任意组件间的通信,有效简化了开发过程中一些数据传递的操作,同时也提高了程序的性能,但是值得注意的是,全局事件总线之所以叫全局,是因为任何组件都可以访问,这就导致如果大量组件都绑定了全局事件总线,难免会造成代码混乱,且自定义事件名可能发生重复的问题,所以在开发中,使用全局事件总线时要根据实际业务情况进行选择。

  1. 全局事件总线:一种组件间通信的方式,适用于任意组件间通信。

  2. 安装全局事件总线:

    new Vue({
    	......
    	beforeCreate() {
    		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    	},
        ......
    }) 
    
  3. 使用事件总线:

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

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }
      
    2. 触发事件+提供数据:this.$bus.$emit('xxxx',数据)

  4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。文章来源地址https://www.toymoban.com/news/detail-495195.html

到了这里,关于前端vue入门(纯代码)11的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue2-全局事件总线、消息的订阅与发布、TodoList的编辑功能、$nextTick、动画与过渡

    🥔:高度自律即自由 更多Vue知识请点击——Vue.js 一种组件间通信的方式,适用于任意组件间通信。通俗理解就是一个定义在所有组件之外的公共嘎达,这个嘎达可以有vm或vc上的同款 $on、$off、$emit ,也可以让所有组件都访问到。要想实现这个事情,只能在 Vue.prototype 上添加

    2024年02月11日
    浏览(40)
  • 前端vue入门(纯代码)11

    【 11.全局事件总线(Global Event Bus) 】 全局事件总线:实现任意组件间通信 【原理图】 结合上图,假若C组件想要传递数据给A组件,那么,就通过全局事件总线在A组件中绑定 【$on】 一个自定义事件demo,并界定一个参数来接收传递的数据,同样在C组件中,就需要通过全局事件

    2024年02月10日
    浏览(52)
  • 全栈开发前端代码:黑马程序员SpringBoot3+Vue3全套视频教程,springboot+vue企业级全栈开,big-event

    目录 :希望对大家有帮助 ①项目压缩包: 1.要启动的指令:可以参考下面的文件 ①登录、注册页面 srcviewsloginLoginPage.vue srcapiuser.js srcstoresmodulesuser.js srcstoresindex.js ②首页实现的页面 srcviewslayoutLayoutContainer.vue srcapiuser.js user下面的小模块:实现改用户信息、图像、

    2024年01月18日
    浏览(54)
  • vue3全局事务总线mitt

    vue3中$on,$off 和 $once 实例方法已被移除,组件实例不再实现事件触发接口。可以使用Mitt库(其实就是发布订阅模式的设计) 安装 内置方法 发布事件 使用方法通过emit派发, on 方法添加事件,off 方法移除,clear 清空所有 新建mitt文件夹,index.ts 派发 获取  如果在setup中派

    2024年02月11日
    浏览(69)
  • Android 11 定制系统全局监听触摸事件接口

    1.定义创建aidl接口(由于需要回调这里优先需要增加一个回调接口 ) frameworksbasecorejavaandroidappIOnTouchListener.aidl package android.app; oneway interface IOnTouchListener {      void onTouchEvent( int action); }   2.新增调用接口 在 base/core/java/android/view/IWindowManager.aidl 修改如下: import android.ap

    2023年04月08日
    浏览(55)
  • 自然语言处理从入门到应用——全局向量的词嵌入:GloVe(Global Vectors for Word Representation)词向量

    分类目录:《自然语言处理从入门到应用》总目录 无论是基于神经网络语言模型还是word2vec的词向量预训练方法,本质上都是利用文本中词与词在局部上下文中的共现信息作为自监督学习信号。除此之外,另一类常用于估计词向量的方法是基于矩阵分解的方法,例如潜在语义

    2024年02月09日
    浏览(46)
  • vue3探索——组件通信之事件总线

    Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用 mitt.js 。 比起Vue实例上的 EventBus , mitt.js 好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件的监听和批量移除,它还不依赖Vue实例,所以可以跨框架使用,React或者Vue,甚至jQuery项目都能使用同一套库。 使用yarn安装

    2024年02月12日
    浏览(45)
  • note_前端框架Vue的安装和简单入门(Windows 11)

    (1) 下载安装node.js和npm (2) 使用npm下载安装vue 下面两张图分别展示了项目的创建过程(图1)和创建完成后的目录文件(图2)。 图1. 执行 web init webpackage 后需要依次配置的选项。包括项目名、项目简介、作者、build类型、是否安装vue-router、是否使用ESLint检查代码、ESLint类型、

    2024年02月10日
    浏览(39)
  • Vue面试题:如何使用事件总线进行组件间数据传输?

    问题: 假设你正在为一个大型企业级Vue应用程序编写代码,并且需要在多个组件之间传递数据。其中一个组件需要从另一个组件中获取数据,但是这个组件可能还没有加载完成。在这种情况下,你会采取什么措施来确保数据的可靠传输?请提供代码示例来解释你的解决方案。

    2023年04月09日
    浏览(40)
  • vue3中事件总线mitt(第三方库mitt)

    1.安装mitt:npm install mitt -save 2. 新建EventBus.js文件: 3.发出事件的页面:bb.vue 4.接收事件的页面:dd.vue 5.点击bb页面按钮:

    2024年02月14日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包