vue事件车的原理与标准写法实现兄弟组件的传值
创始人
2024-05-16 10:13:08
0

目录

  • 前言
  • 一,全局事件总线介绍
    • 1.1 原理介绍
    • 1.2 x需要满足的条件
  • 二,知识点的复习
    • 2.1 vc是什么
    • 2.2 vm管理vc如何体现
    • 2.3 原型
    • 2.4 上述知识的串联
  • 三,实现需求
    • 3.1 x的编写及讲解
    • 3.2 使用x
  • 四,标准写法
    • 4.1 写法改动
    • 4.2 销毁
  • 五 关键代码
  • 后记

前言

在没有学习兄弟组件的传值时,兄弟组件之间传值可以借助它们共同的父组件:把值传给它们的父组件,再按需要取值(子传父,父再传子)。这样做十分麻烦,本节将提供更简单的做法——事件总线。

注意,本节内容最好是在熟悉了父子组件的相互通讯的前提下再进行学习,如果不太熟悉可以参考下面两篇博客(第二篇文章原理讲解更多):Vue组件之间的数据共享详解

一,全局事件总线介绍

1.1 原理介绍

如图,组件结构图如下。现在我们有一个需求,想要将D组件中的数据以参数的形式传递给A组件。
在这里插入图片描述

怎么实现呢?利用以前的想法,我么可以让D组件先把数据传递给App组件,然后A组件再从App组件中获取数据。这个过程可以利用给组件设置自定义事件来实现。在这个过程中,App组件成了一个联络人。但是这样的方法,其实是绕了很大一个湾子去实现目的。

本节,我们将介绍一个很简单的方法:设置一个x,要求x也可以充当向上面app一样的联络人。如下图所示:同样是将信息从D传到A。我们可以在过程1中,在A中给x绑定一个自定义事件demo,在2过程中,x身上的demo事件被触发,x事件的回调在A中执行,参数成功传给了A。
在这里插入图片描述

1.2 x需要满足的条件

通过上述的讲解,可以看出x十分重要,那么,现在我们为来探讨x究竟是什么。

x的要求:x需要能够被所有组件看见(所有组件都能访问到x),x还需要能够使用on和emit。

我们可以推理一下,满足第二个条件,x可以是一个vc,也可以是vm。满足第一个条件的,也可以是一个vc或者是vm。

上面说了很多vc和vm,为了方便大家学习,在第二节会说清vc和vm的关系,以及对一些相关知识的复习。如果知识很熟可以跳过。

二,知识点的复习

2.1 vc是什么

vc的全称VueConpoment。vc的本质是一个构造函数。

而我们每写一个组件,组件的本质就是vc,也就是构造函数。

每用一个组件在App中,那么就相当于该组件多了一个组件的实例对象。

一个组件在做项目时会被复用多次,这些被复用的就是组件的实例对象:
在这里插入图片描述
在这里插入图片描述

2.2 vm管理vc如何体现

体现vm为何能管理vc,只需要看vm中是否有vc:
在这里插入图片描述

2.3 原型

这里要从构造函数聊起,在es6之前,没有类和对象,但是通过构造函数与构造函数的实例对象同样也可以实现面向对象编程。

在构造函数的相关知识中,构造函数的每一个实例对象都可以使用构造函数中的方法,但是有一个弊端:占用内存。如下图:
在这里插入图片描述
在这里插入图片描述
如何解决弊端:原型。构造函数中的原型:prototype,如果我们不把方法放在构造函数中,而是放在构造函数的原型对象上,依旧可以实现共享,并且不会占用内存。
在这里插入图片描述
在这里插入图片描述
原型中的方法是所有构造函数的实例对象共享的。也就是说,所有的实例对象都可以访问原型中的方法。

以上就是对原型知识的普及,如果觉得不够,可以查看博客:构造函数与原型对象,这里有对相关知识的详细讲解。

2.4 上述知识的串联

以上是我在学习这一块时复习的知识,以及引发的一些思考。为什么要讲解上述知识,我们回到对x的要求上。x需要能够被所有的组件看见,我们可以考虑把x放在prototype上;x需要能够使用on和emit,而组件可以,vm管理vc,所以vm也可以。因此,x可以是一个新的vm也可以是一个新的vc。这块知识可能有些晦涩,下面会结合实例理解。

三,实现需求

3.1 x的编写及讲解

如图所示,在main.js中定义一个vc并把它放到原型上去:
在这里插入图片描述
这里我来解释一下Demo是什么。Vue.extend()用来创建一个组件。组件本质是一个构造函数,由Vue.extend()自动生成。
如果向了解extend用法可以参考此博客:用原生的方式写vue组件之深度剖析组件内部的原理。
Demo是一个组件(构造函数),那么demo就是Demo的实例对象。Vue.prototype.x=demo, 是在Vue原型上创建了一个x。然后x是一个组件的实例对象。由于Vue的原型可以被所有组件实例对象访问,所以x可以被所有组件实例对象访问;而demo本质是一个组件的实例对象,所以可以使用on和emit,因此就达到了对x的两个要求。

3.2 使用x

那么,既然已经写好了x我们就可以来用到x了。如下图所示,这是要传递信息的一方,相当于刚说的A,在A中利用on给x定义一个自定义事件hello,并且后面有一个回调函数。如果对自定义方法不了解可以参考此博客:vue中利用ref实现更灵活的子向父传值中有涉及到。
在这里插入图片描述
既然已经绑定在了x上,我们可以在传值方使用emit调用此自定义方法:
在这里插入图片描述
这样一来就可以实现兄弟组件的数据传递。

四,标准写法

4.1 写法改动

标准写法的原理与上面一样。
标准写法同样是在main.js中,不同的是,x改为$bus,这个名字是为了适应vue的取名风格,其实什么名字都不重要,x也可以;还有就是,之前是创建了一个组件的实例对象,现在直接把vm拿出来,如下图所示:
在这里插入图片描述
这里需要解释几个问题:

1.使用beforeCreate:是因为,一般使用兄弟组件互传数据,最终的目的大多是为了使用数据,并呈现在页面上。而beforeCreate钩子时,数据监测数据代理都没有实现,且访问不到data的数据,所以数据要在还没有对数据进行处理的时候完整。

2.为什么用this:之前我们说可以用vm,但是如果在vm定义好后等于vm,页面已经更新完成,此时 $bus就没什么意义。如果在vm定义前等于vm,vm并未存在,无法令值为vm;所以利用钩子函数,后面赋值为this,是标准写法。

既然改动了$x,那么所有的 $x都要改为 $bus

学习了上面的原理,大家应该都对$bus有了了解,它叫事件总线,还叫事件车,组件之间的传递可以通过它来实现。

4.2 销毁

上文交代了事件车的原理,组件间数据的传递都可以用到它,但一般在使用中,一旦用完,为了加快项目运行的效率我们最好在beforeDestory钩子中解绑档期那组件所用到的事件,注意,只是销毁那个事件,而不是销毁所有。如下图所示,利用off即可。
在这里插入图片描述

五 关键代码

main.js

import Vue from 'vue'
import App from './compoments/App'//写一个demo组件// const Demo = Vue.extend({})//demo是组件的g构造函数
// const demo = new Demo()//组件的实例对象
// Vue.prototype.x = demonew Vue({el: '#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this//标准写法,安装全局事件总线}
})

App.vue


接受数据的一方:


传数据的一方:


后记

以上是对事件车的原理讲解与写法说明,希望本节内容可以帮到读者朋友。有什么不对之处欢迎大家批评指正,同时也欢迎关注,后期会带来更认真的内容!

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...