vue (兄弟|非父子组件通信)

本文详细介绍了Vue中组件通信的各种方法,包括父子组件的props和$emit,跨级组件的逐层传递,以及兄弟组件间的Bus总线通信模式。通过实例演示了如何使用$bus进行事件分发、监听和取消监听,强调了在组件通信中避免命名冲突和防止事件多次触发的重要性。最后提到了Vuex作为状态管理工具在大型项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有人可能会问:为什么要学习组件通信

原因:
在实际开发中我们经常会遇到在一个自定义组件中要使用其他自定义组件,这就需要一个父子组件关系,进而引出互相通信的问题。

父子组件传值通信

假设第二层组件想和第一层组件进行通信,分析其传值过程
1、(第一层向第二层传值):父组件通过props传值到子组件,如此便实现父子组件向下通信
2、(第二层向第一层传值):子组件通过触发自定义事件$emit向父组件传值,如此便实现了父子组件向上通信
在这里插入图片描述

跨级组件传值通信

假设第三层组件想和第一层组件进行通信
1、(第一层组件向第三层组件传值)—禁止第一层直接传值到第三层,需要逐层传递,即1→2→3,此时便可以实现跨级组件向下通信
2、(第三层组件向第一层组件传值)—通过触发自定义事件将数据传递至第二层,然后第二层通过事件触发传递至第一层,如此逐层传递,便可以实现跨级组件向上通信

兄弟组件通信

兄弟组件传值通信
假设第三层组件想和同层的另一个组件进行通信。
如果还是逐层传递至第二层,再由第二层传递至第三层,此时代码量十分累赘复杂,这也不符合Vue的定义(Vue是一个轻量级的视图层框架)。
在这里插入图片描述

引用官方文档:
因为基于组件树结构的事件流方式让人难以理解,并且在组件结构扩展的过程中会变得越来越脆弱。这种事件方式确实不太好,我们也不希望在以后让开发者们太痛苦。
官方推荐的状态管理方案是 Vuex。不过如果项目不是很大,状态管理也没有很复杂的话,使用 Vuex 有种杀鸡用牛刀的感觉,当然,这也是要根据自己的需求来的。
本节介绍下另一种方法,即bus/总线/发布订阅模式/观察者模式来解决

文档术语:
通过使用事件中心,允许组件自由交流,这个集中式的事件中间件就是 Bus总线。

语法:
在组件中使用$emit, $on, $off 分别来分发、监听、取消监听事件

接下来依次做下介绍

首先定义两个兄弟组件,如下所示

在这里插入图片描述

要求:点击一个组件,另一个兄弟组件也发生改动,两者数值相等

兄弟组件通信
接下来结合案例,介绍下如何通过bus/总线/发布订阅模式/观察者模式来解决非父子组件通信。

第一步(注册全局bus总线):
创建一个Vue实例,将其赋值给Vue.prototype.bus
在这里插入图片描述

解析:在Vue的prototype类上挂载了一个bus属性,该属性指向Vue实例。只要在其后通过Vue实例创建组件,则每个组件都会有bus属性

第一步(注册全局bus):
写法2:Vue bus的使用(兄弟|非父子组件传值)–>可以使用一个空的Vue实例作为中央事件总线new Vue(),此外也可以写成$bus

在这里插入图片描述
有人可能会问“为什么加$,作用是什么”?

接下来简单介绍下$作用

$命名法则

简介:
$ 是在 Vue 所有实例中都可用的属性的一个简单约定。这样做会避免和已被定义的数据、方法、计算属性产生冲突,即避免命名冲突。接下来结合案例测试下

在这里插入图片描述
接下来,在data数据里声明个同名的变量,如下所示
在这里插入图片描述
修改代码如下所示
将Vue挂载实例命名前,加上前缀$,用于避免和已被定义的数据、方法、计算属性产生冲突,即避免命名冲突。

在这里插入图片描述
接下来继续介绍兄弟组件通信
再来梳理下需求,即当点击某个组件改变时,希望同时触发另外一个非父级组件改动,所以接下来需要在子组件绑定事件
在这里插入图片描述
第二步:通过中央事件线程$ bus,分发事件属性$emit

在这里插入图片描述

解析:
this. b u s 为 中 央 事 件 总 线 程 n e w V u e 实 例 , 通 过 bus为中央事件总线程new Vue实例,通过 bus线newVueemit来分发事件,分发事件时可以携带参数option。
子组件分发完毕后,其他组件需要进行监听接收分发的事件,此时可以借助生命周期钩子来实现。
第三步:
结合生命周期钩子监听和接收分发的事件,监听事件属性$on。
在这里插入图片描述

结合生命周期钩子监听和接收分发的事件,监听事件属性$on。
接下来修改数据
在这里插入图片描述

结合生命周期钩子监听和接收分发的事件,监听事件属性$on。
解决方案之前说过,利用子组件data,拷贝份父组件传递数据,后续即可维护自身数据,而不改动父组件数据

在这里插入图片描述
第四步:取消|清除监听事件,取消监听属性$off
日常开发里,为了避免不要的BUG,建议在使用bus时,加上清除监听操作,代码如下
在这里插入图片描述
如果需要监听多个组件,只需要更改 bus 的 eventName
在这里插入图片描述

步骤小结:
1、注册全局 $ bus
使用空Vue实例作为中央事件总线new Vue(),注册全局$bus总线
2、分发 $ emit:
通过中央事件线程 b u s , A 组 件 , 分 发 事 件 属 性 bus,A组件,分发事件属性 busAemit
3、监听 $ on:
结合生命周期钩子,B组件监听和接收分发的事件,监听事件属性 $on。
4、取消 $ off:
取消|清除监听事件,取消监听属性 $ off

引用官网的一句话:
父子组件的关系可以总结为 prop 向下传递,事件向上传递
父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:
在这里插入图片描述
如果需要子对子传参,可以先从传到父组件,再传到子组件,但这样写过于累赘。

方案:
为了便于开发,vue 推出了一个状态管理工具 vuex,可以很方便实现组件之间的参数传递,后期结合工程化介绍。
官方推荐的状态管理方案是 Vuex。不过如果项目不是很大,状态管理也没有很复杂的话,使用 Vuex 有种杀鸡用牛刀的感觉。所以本节介绍下另一种方法,即bus/总线/发布订阅模式/观察者模式来解决

跨级通信方案
使用 a t t r s 和 attrs和 attrslisteners实现祖孙组件之间的数据传递,也就是多重嵌套组件之间的数据传递

版本注意:
本方法针对vue2.4版本及以上,使用 a t t r s 和 attrs和 attrslisteners来实现的

首先看下跨级组件通信自上而下步骤,案例如下
在这里插入图片描述
跨级组件通信自上而下
祖父级:用于动态数据的绑定与事件的定义
父级:通过设置v-bind=" a t t r s " 和 v − o n = " attrs" 和v-on=" attrs"von="listeners"来充当中间人
孙子级:通过 a t t r s 和 attrs和 attrslisteners来获取数据和事件

一般来说,自上而下的通信会涉及到props与$attrs,而自下而上的通信,都是通过事件触发,然后层层上传。在这里插入图片描述
跨级组件通信自下而上
方案一:
$emit逐层上传

在这里插入图片描述
跨级组件通信自下而上
方案二:通过$listeners接收事件
在这里插入图片描述

常见组件通信BUG

(1)bus. o n 监 听 多 次 绑 定 , 造 成 事 件 多 次 触 发 问 题 描 述 : 只 要 页 面 没 有 强 制 刷 新 , 存 在 组 件 切 换 , b u s . on监听多次绑定,造成事件多次触发 问题描述:只要页面没有强制刷新,存在组件切换,bus. onbus.on方法会被多次绑定,造成事件多次触发
方案:注册的总线事件(Bus)要在组件销毁时(beforeDestroy/destroyed)卸载,否则会多次挂载,造成触发一次但多个响应的情况
在这里插入图片描述

方案2:在每次调用方法前先解绑事件bus.$ off ,然后在重新绑定bus.$on ,该做法不常用,简单了解即可。

总结

(1)数值传递大概可以分为两种,即父子传值与非父子传值
(2)非父子传值包含:跨级传值、兄弟传值
(3)父向子传递:props
(4)子向父传递: e m i t ( 5 ) 兄 弟 之 间 传 递 : 借 助 中 间 代 理 , 即 中 央 事 件 总 线 emit (5)兄弟之间传递:借助中间代理,即中央事件总线 emit5线bus
使用$emit, $on, $off 分别来分发、监听、取消监听事件
(6)跨级通信:
a t t r s 可 以 获 取 父 作 用 域 传 入 的 值 ( 不 包 括 p r o p s 中 的 ) , attrs可以获取父作用域传入的值(不包括props中的), attrspropslisteners相当于父作用域的事件监听器,那我们就可以用这两个属性实现祖孙之间的数据通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值