已经介绍了两种组件间通信的方法:provide / inject 和 dispatch / broadcast。它们有各自的使用场景和局限,比如前者多用于子组件获取父组件的状态,后者常用于父子组件间通过自定义事件通信。

本文将介绍第 3 种组件通信方法,也就是 findComponents 系列方法,它并非 Vue.js 内置,而是需要自行实现,以工具函数的形式来使用,它是一系列的函数,可以说是组件通信的终极方案。findComponents 系列方法最终都是返回组件的实例,进而可以读取或调用该组件的数据和方法。

它适用于以下场景:

  • 由一个组件,向找到最近的指定组件;
  • 由一个组件,向找到所有的指定组件;
  • 由一个组件,向找到最近的指定组件;
  • 由一个组件,向找到所有指定的组件;
  • 由一个组件,找到指定组件的兄弟组件。

5 个不同的场景,对应 5 个不同的函数,实现原理也大同小异。

实现:

5 个函数的原理,都是通过递归、遍历,找到指定组件的 name 选项匹配的组件实例并返回。

向上找到最近的指定组件——findComponentUpward

先看代码:

findComponentUpward 接收两个参数,第一个是当前上下文,比如你要基于哪个组件来向上寻找,一般都是基于当前的组件,也就是传入 this;第二个参数是要找的组件的 name 。

findComponentUpward 方法会在 while 语句里不断向上覆盖当前的 parent 对象,通过判断组件(即 parent)的 name 与传入的 componentName 是否一致,直到直到最近的一个组件为止。

与 dispatch 不同的是,findComponentUpward 是直接拿到组件的实例,而非通过事件通知组件。比如下面的示例,有组件 A 和组件 B,A 是 B 的父组件,在 B 中获取和调用 A 中的数据和方法:


使用起来很简单,只要在需要的地方调用 findComponentUpward 方法就行,第一个参数一般都是传入 this,即当前组件的上下文(实例)。

上例的 comA,保险起见,加了一层 if (comA) 来判断是否找到了组件 A,如果没有指定的组件而调用的话,是会报错的。

findComponentUpward 只会找到最近的一个组件实例,如果要找到全部符合要求的组件,就需要用到下面的这个方法。

向上找到所有的指定组件——findComponentsUpward

代码如下:

与 findComponentUpward 不同的是,findComponentsUpward 返回的是一个数组,包含了所有找到的组件实例。

findComponentsUpward 的使用场景较少,一般只用在递归组件里面(后面小节会介绍),因为这个函数是一直向上寻找父级(parent)的,只有递归组件的父级才是自身。事实上,iView 在使用这个方法也都是用在递归组件的场景,比如菜单组件 Menu。由于递归组件在 Vue.js 组件里面并不常用,那自然 findComponentsUpward 也不常用了。

向下找到最近的指定组件——findComponentDownward

代码如下:

context.$children 得到的是当前组件的全部子组件,所以需要遍历一遍,找到有没有匹配到的组件 name,如果没找到,继续递归找每个 的

children,直到找到最近的一个为止。

来看个示例,仍然是 A、B 两个组件,A 是 B 的父组件,在 A 中找到 B:


示例中的 A 和 B 是父子关系,因此也可以直接用 ref 来访问,但如果不是父子关系,中间间隔多代,用它就很方便了。

向下找到所有指定的组件——findComponentsDownward

如果要向下找到所有的指定组件,要用到 findComponentsDownward 函数,代码如下:

这个函数实现的方式有很多,这里巧妙使用 reduce 做累加器,并用递归将找到的组件合并为一个数组并返回,代码量较少,但理解起来稍困难。

用法与 findComponentDownward 大同小异,就不再写用例了。

找到指定组件的兄弟组件——findBrothersComponents

代码如下:

相比其它 4 个函数,findBrothersComponents 多了一个参数 exceptMe,是否把本身除外,默认是 true。寻找兄弟组件的方法,是先获取 context.$parent.$children,也就是父组件的全部子组件,这里面当前包含了本身,所有也会有第三个参数 exceptMe。Vue.js 在渲染组件时,都会给每个组件加一个内置的属性 _uid,这个 _uid 是不会重复的,借此我们可以从一系列兄弟组件中把自己排除掉。

举个例子,组件 A 是组件 B 的父级,在 B 中找到所有在 A 中的兄弟组件(也就是所有在 A 中的 B 组件):


在 ① 的位置,打印出的内容为空数组,原因是当前 A 中只有一个 B,而 findBrothersComponents 的第三个参数默认是 true,也就是将自己除外。如果在 A 中再写一个 B:

这时就会打印出 [VueComponent],有一个组件了,但要注意在控制台会打印两遍,因为在 A 中写了两个 B,而 console.log 是在 B 中定义的,所以两个都会执行到。如果你看懂了这里,那应该明白打印的两遍 [VueComponent],分别是另一个 (如果没有搞懂,要仔细琢磨琢磨哦)。

如果将 B 中 findBrothersComponents 的第三个参数设置为 false:

此时就会打印出 [VueComponent, VueComponent],也就是包含自身了。

以上就是 5 个函数的详细介绍,get 到这 5 个,以后就再也不用担心组件通信了。

调用父级方法_通信:找到任意组件实例的findComponents系列方法,5个终极方案相关推荐

  1. 织梦调用父级栏目名称

    1.打开include/taglib/type.lib.php,找到 $row['typelink'] = $row['typeurl'] = GetOneTypeUrlA($row); 在其下面增加 ...

  2. java 调用父级方法_java子类调用父类的方法是什么

    java子类调用父类的方法:1.子类的对象调用方法时,会首先在子类中查找,如果子类中没有该方法,再到父类中查找:2.如果该方法中又调用了其他方法,那么还是按照之前的顺序,先在子类中查找,再在父类中查找 ...

  3. python用类名直接调用方法_一文读全 Python 的面向对象编程方法

    背景介绍: Python 支持三种形式的编程,分别是:"命令式"."函数式"和"面向对象式". 很多优秀的开源 Python 项目里都用到了 ...

  4. go 调用其他文件函数_一篇文章让你了解Go语言中方法Methods的使用内幕

    概述 Go语言中的方法只不过是一个带有接收器的函数.接收器是某个特定类型(如struct)的实例,或是任何其他自定义类型的实例.所以基本上,当你把函数附加到类型上时,该函数就成为这个类型的一个方法.方 ...

  5. 华为交换机关机方法_华为交换机常用的三种vlan划分方法~

     点击"华为考试HCIE俱乐部"→点击右上角"..."→"设为星标"   资讯丨干货丨入群 联系小E微信:SPOTO123456 作为华为设 ...

  6. java获取随机数方法_《Java语言程序设计》Java获取随机数方法

    <Java语言程序设计>Java获取随机数方法 在Java中我们可以使用java.util.Random类来产生一个随机数发生器.它有两种形式的构造函数,分别是Random()和Rando ...

  7. java 找出调用的方法_如何找到用Java调用给定方法的所有方法?

    小编典典 为了分析字节码,我建议使用ASM.给定要分析的类列表,可以使访问者找到您感兴趣的方法调用.下面是一个分析jar文件中类的实现. 请注意,ASM使用带有'/'而不是'.的internalNam ...

  8. java 调用父级方法_java子类调用父类的方法中包含子类重写的实例方法

    # 看题目是不是很绕,这个我也不知道怎么才能更简单的表达了 # 先看代码: public class Common { public static void main(String[] args) { ...

  9. html调用rpst 源码_在web页面中播放rtsp直播数据流方法

    WEB播放RTSP直播数据流方法 附录一些RTSP测试地址: 1.rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov 一段动画片 2.rtsp: ...

最新文章

  1. C++预处理程序指令
  2. 51 Nod 1007 正整数分组【类01背包】
  3. 【案例】数据量猛增,BI分析效率太低怎么破?
  4. ZZULIOJ 1085: 求奇数的乘积(多实例测试)
  5. Kafka源码解析 - 副本迁移任务提交流程
  6. log4j.appender.stdout.layout.ConversionPattern
  7. .net学习---ADO
  8. 解决【npm ERR! Unexpected end of JSON input while parsing near '...sh_time:141072930277'】方案...
  9. 一文通俗理解最大似然估计· 看不懂你打我,无公式
  10. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第6节 Lambda表达式_2_冗余的Runnable代码...
  11. Win11硬盘安装方法介绍 Win11系统硬盘安装教程
  12. 低版本内核编译奇怪错误
  13. HTML 转义字符nbsp; ensp; emsp;thinsp;zwnj;zwj;空格标记
  14. 性能测试:一种计算 TP90、TP95 和 TP99 等水位线的方法
  15. 【buildroot】buildroot的相关make命令
  16. QQ币批发、低价的游戏点卡、手机充值卡批发商,大家千万不要相信!我已经上当了。【聊天记录】...
  17. vacuum 数据库 用法_[数据库学习]第二章SQL命令参考-VACUUM
  18. Java——this关键字(调用本类属性、调用本类方法、表示当前对象)
  19. 证书 Certificate
  20. MicroBlaze:Xilinx官方软核学习与一些实验测试

热门文章

  1. 博客迁移至http://www.vlix.org/
  2. 黑马程序员java笔记之二-----多线程
  3. QT 的信号与槽机制介绍
  4. 嵌套类可以先在外围类中声明,然后在外围类中定义
  5. Ext 整合 Jquery
  6. 大家买PDA干什么,来看SPB的调查
  7. 洛谷p1208 水题贪心 思想入门
  8. easyui英文提示变中文
  9. nyoj 234 吃土豆
  10. iptables 定义规则