-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vue源码学习系列之十一:组件化原理探索(父子组件通信) #94
Labels
Comments
youngwind
changed the title
vue早期源码学习系列之十一:组件化原理探索(父子组件通信)
vue源码学习系列之十一:组件化原理探索(父子组件通信)
Oct 12, 2016
学习了~👍 |
希望楼主多出些这类文章,太受益了~ |
看了你的文章受益良多,老铁可不可以写篇关于javascript的eventloop的博文。或者老铁可不可以帮我解惑一下关于eventloop的问题https://segmentfault.com/q/1010000008960948?_ea=1787342 |
嗯嗯,看了知乎上讨论的那个,明白了不少,thx @youngwind |
厉害~ 关注你的博客半年了, vue的源码系列断断续续看完了,也自己实现了一套。 非常感谢!! 以后会持续关注你的博客 |
vue父子组件通信是基于props属性来实现的 不是基于发布订阅吧 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前言
继 #93 之后,我们来探索如何实现Vue的父子组件通信。
在问如何实现之前,我习惯性地思考为什么。
为什么Vue、React这些MVVM框架会出现组件通信这个概念?犹记得我去年初刚刚学前端的时候,学的还是jquery,那时候还没接触组件的概念,所有的DOM都写到一块,A处的DOM和B处的DOM并没有明确的边界。如果A处的DOM想修改B处的DOM,那么一定是A处的DOM触发某个js方法,然后该js方法直接修改B处的DOM。就这样,非常原始,也非常符合js这门脚本语言的风格。
然而,前端早已非“当年吴下阿蒙”。在不断吸收传统软件开发优良思想的过程中,前端已经越来越系统化,js也逐渐成为一门正规的语言。组件化的概念其实就很类似传统软件开发中的模块化(各模块之间有明确的边界),既然划分了模块,那么模块之间的通信自然就成为了要解决的问题。这就是为什么这些MVVM框架会出现组件通信这个概念。
目标
本文只解决父子组件通信,不解决兄弟组件通信。预期做到的效果如下所示。
注意:图中展示的效果总共有三层实例/组件,层层嵌套。他们之间传递“姓名”和“年龄”两个字段,又分为”向上冒泡“和”向下广播“两个方向,所以总共有2*2=4种事件。其中,在冒泡(dispatch)和广播(broadcast)的过程中,”姓名“事件的传递不会停止,而”年龄“事件在触发第一次的回调函数的时候,就会停止冒泡或广播。如果希望在首次触发回调之后继续冒泡或广播,那么须在events事件中指定
return true
。这与vue的实现保持一致。PS: 此处示例对应的代码比较长,就不在文中展示了,请直接阅读源码,或者运行项目直接debug。
思路
我们考察child组件,发现它跟一般的组件有以下两点不同:
先来看第一点。
事件初始化
我们需要将事件及其回调函数注册到child实例上,这样当其他组件(无论是父组件还是子组件)传来消息的时候,程序才能知道该触发哪个事件,该执行哪个回调函数。
初始化的结果可以参考下图。
触发及传播事件
无论是$dispatch还是$broadcast,他们都有类似的步骤。
如果是向上冒泡事件
return true
,那么代表事件可传播,执行第2步。如果事件不可传播,结束。如果是向下广播事件
return true
,那么代表事件可传播,重新执行第1步。如果事件不可传播,结束。相关代码如下:
注意:Vue在广播事件的时候,是不会在发起广播事件的组件触发该事件的,只会从它的下一个子组件开始触发。这与冒泡事件稍有不同。
That's all。这样我们就实现了Vue父子组件之间的通信了。参考的Vue源码依然是1.0.26版本,实现的完整代码在这儿。
后话
虽然我们实现了父子组件通信,但是,兄弟节点A、B间怎么通信呢?一个比较粗糙的思路就是:兄弟A将消息发到兄弟A、B共同的父节点C,然后再经由C转发给兄弟B。但是这样做有一个弊端,当节点很多的时候,这种传递方式就会显得杂乱无章。那么,传统的计算机是如何解决众多兄弟节点(比如,CPU、内存、硬盘等等)之间的通信的呢?答案是总线机制。这么良好的思想,我们前端怎么能不借鉴呢?所以就有了redux和vuex这些状态管理器。
The text was updated successfully, but these errors were encountered: