实现双向数据绑定
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现双向数据绑定相关的知识,希望对你有一定的参考价值。
参考技术A 在上篇文章当中,我们实现了单向数据绑定,那么接下来,咱们一步一步来实现双向数据绑定。首先最大的问题就是我们如何去知道data里面的数据变化了,在Vue的实例化对象的data属性当中,可以查看到该属性上存在着一个get和set方法,而这两个方法实际上是通过Object.defineProperty()来实现数据劫持的。
先来实现一个简单的需求,创建一个简单的对象。
但是现在我想要在获取到Book.name的时候有个书名号包裹着该怎么办呢?这就需要用到上文说到的Object.defineProperty()了。
通过Object.defineProperty( )设置了对象Book的name属性,对其get和set进行重写操作,get就是在读取name属性这个值触发的函数,set就是在设置name属性这个值触发的函数。而在控制台输出的Book对象,乍一看,和Vue的数据长得有点类似,说明Vue确实是通过这种方法来实现数据的劫持的,那么我们就可以实现一个监听器observer了。
有了observer方法,我们就能够去实现监听Vue实例化对象的data属性值是否发生了更改,也就是说在Vue类当中调用observer方法即可,但是现在只是知道了哪个属性发生了变化,却无法实时的更新,要想实现这一步,我们先来考虑一个问题,当某一个属性值发生变化的时候,是需要将所有绑定该属性值的节点的值改为该属性值,所以这就用到了发布和订阅模式,也就是说,绑定同一个属性的每一个订阅者都存放在同一个订阅器内,如果该属性值变化了,订阅器会逐个的发布告知每一个订阅者。(更多详细信息请自行百度或参考 lk儒家 博客)
根据理解,很容易的清楚的知道需要一个订阅者容器类,该类的实例化对象必须含有一个数组,然后有一个向该数组存放订阅者的方法,以及循环该数组通知所有订阅者更新的方法。
而对于订阅者,上文也进行分析了,也很清楚的知道每一个订阅者的实例上都存在着一个update方法,即更新其内容,而再仔细想一想,这些订阅者到底是什么,更新的是什么内容呢?是不是每一个绑定Vue的属性的节点都是一个订阅者,改变的是该节点的内容,也就是说,这些订阅者是在上篇文章当中compile的时候去创建,需要的参数值是Vue的实例化对象,绑定的该节点以及绑定的Vue的属性值。
而现在我们剩下的问题就是observer和Watcher并没有关联到一起,细心的小伙伴可能已经发现了在Watcher类当中进行了一句初始化操作,而执行update方法为什么属于初始化呢?可以发现,在update方法当中是将this.vm.data[this.name]赋值给节点内容,而this.vm.data[this.name]早已经被监听了,即其会在赋值之前先执行该Vue实例化对象data属性的get方法,所以向订阅者容器当中添加订阅者的操作就是在监听的get方法当中,那么又该如何区分是否是需要添加的呢,这里可以在Watcher类当中添加一个标识,例如Dep.target,因为这个是全局的,所以在每一次操作完后就要对该值释放。
到此为止,整个Vue的双向绑定原理基本上说完了,但是运行发现,当修改输入框内容的时候,绑定同样属性值的内容根本就没有变化,这是由于没有给输入框绑定keyup事件,在该事件当中,只需要将输入框的内容赋值给Vue实例化对象的data中的绑定属性即可。
最后,奉上一张逻辑图,加深理解,biubiu!
Angular 手动实现ngModal数据双向绑定
参考技术A Angular中我们在formsModule中使用ngModel实现数据的双向绑定这里的ngModel其实是个语法糖,它等价与属性绑定+事件绑定,就像下面这样
也可以写成普通的属性绑定+普通事件
自己来实现一个双向绑定
父组件
子组件html:
子组件ts
这样就完成了, 对于父组件来说,就是实现了子组件的数据双向绑定!
以上是关于实现双向数据绑定的主要内容,如果未能解决你的问题,请参考以下文章