实现双向数据绑定

实现双向数据绑定,第1张

在上篇文章当中,我们实现了单向数据绑定,那么接下来,咱们一步一步来实现双向数据绑定。

首先最大的问题就是我们如何去知道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!

双向数据绑定指的就是,绑定对象属性的改变到用户界面的变化的能力,反之亦然。换种说法,如果我们有一个user对象和一个name属性,一旦我们赋了一个新值给user.name,在UI上就会显示新的姓名了。同样地,如果UI包含了一个输入用户姓名的输入框,输入一个新值就应该会使user对象的name属性做出相应的改变。

详细的解释和例子可以看下这篇文章,http://www.php.cn/js-tutorial-4385.html,希望对你有帮助


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/7433775.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-05
下一篇2023-04-05

发表评论

登录后才能评论

评论列表(0条)

    保存