(1)prop的实现
子组件拿到父组件赋值的 attr=> 筛选出 props并保存在子组件的_props里=>_props中的数据逐一复制到子组件的实例上(同时设置get 和 set )
当父组件data更新,渲染函数执行,又会执行上面的赋值。由此就达成了父组件的数据变化时,子组件props更新的效果。
但是很明显,当我们操作子组件中的props时实际上我们是在操作子组件的_props,这完全不会影响到父组件的数据。单纯靠props我们无法做到父子组件的数据双向绑定。
为什么vue要如此实现。在vue1.0的文档上是这么解释的:
根据文档的解释,这样的单向数据流主要是为了防止子组件意外地改变父组件的状态,防止应用中的数据流变得混乱。
(2).sync的实现
不过vue1.0时官方依然提供了一个能够强制实现双向数据流的办法:.sync修饰符(这个版本的sync的实现,我暂时没找到源码在哪里,有兴趣的可以去翻一下)
这个修饰符在vue2.0的时候被弃用了
主要是为了避免隐式双向绑定,强制性的要求需要显式的传递一个事件。
不过在vue2.3的时候又被添加了回来,但实现原理有所不同
从上面的源码可知 vue2.3版本的.sync修饰符只是一个简单地语法糖。
使用时可以理解为将
<child :foo.sync="data"/>
扩展为了
<child :foo="data" @update:foo="val => data = val"/>
所以在使用时需要在子组件中手动触发一个事件,而非直接修改prop
this.$emit('updata:foo',newVal)
总结
从官方文档能够看出,vue对于组件间传值的设计思路,似乎从早期的版本就固定为 propsDown emitUp一直没变,只是在早期版本有.sync这个例外。在后期版本为了规范,删除了能够实现隐式双向绑定的.sync。
而单向数据流的优势也很明显,就是为了防止子组件意外地改变父组件的状态,防止应用中的数据流变得混乱。