You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<divid="app"><my-component:name="user.name1" message="近况如何?"></my-component><my-component:name="user.name2" message="How are you?"></my-component></div>
前言
在上一篇 #92 中,我们已经实现了通过静态props传递数据,今天我们来看看,如何实现动态props传递数据。
问题具象
考虑下面的情况
注意:组件
<my-component>
有两个prop,其中name是动态prop,message是静态prop。我们的目标是:在正确渲染组件的前提下,当#app的user.name1或者user.name2发生改变的时候,
<my-component>
实例对应地发生改变。思路
我们把上面的大目标分解成下面两个小目标。
要实现第二点,又有两种思路:
显然,第二种方式更为简洁,父子实例之间只需要进行一次通信。
但是第二种方式有一个关键点还没想通:程序如何知道,当父实例的哪个数据发生改变时,要修改子组件对应的数据呢?也就是说,如何将父实例的数据与子组件的动态prop一一映射起来?
这个问题似曾相识,因为我们曾经解决过:
没错,我们采取的的思路跟
如何实现动态数据绑定
#87 一模一样,所以可以直接复用Directive、Watcher这一套东西。ok,思路理清之后,开始敲代码。先从解析props(包括动态和静态的)开始。
解析props
我们从改造之前写好的_initProps方法入手。
其中的getBindAttr函数是为了获取动态prop的值,无论是
b-bind:name="user.name"
还是:name="user.name"
都会被当做动态prop,这跟vue的缩写处理是一样的。应用props
上面我们已经成功将所有的prop(包括静态prop和动态prop)都从
<my-component b-bind:name="user.name" message="hello"></my-component>
上面解析出来了,解析的结果是一个props数组。接下来我们来看看如何应用这个props数组。再次明确一下思路,无论是静态还是动态prop,都需要直接将属性塞到组件的$data当中去。如果是动态属性,还需要走Directive、Watcher那一套。
请注意,这里的compileGetter是之前已经实现的,目的是**根据给出的path路径,从数据对象中解析出对应的数据。**在实现计算属性的文章有提到过。 #89
prop指令
既然prop要走指令那一套,那么就得实现prop指令的bind和update方法。
实现效果
至此,我们已经基本实现了组件动态props传递数据,参考的依然是vue的1.0.26版本,实现的完整代码在这里,实现的效果如下图所示。
下图说明动态prop真的被当成了指令来处理。
后话
在实现组件动态props的过程中,我遇到了一个隐藏得很深的问题:**在目前bathcer实现异步批处理的前提之下,如果在执行某些异步任务的过程中,产生了新的异步任务,该如何处理?**Debug了好一阵了才发现这个微博图,后来我自己想了一个办法临时处理了一下,不过还没完全想明白这样做到底好不好,所以就不在本文展开说了,之后有时间要好好想想。
The text was updated successfully, but these errors were encountered: