vue的双向数据绑定原理

我们可以通过Object.defineProperty()来实现对数据改变的监听。Object.defineProperty()接受三个参数,第一个是目标对象,即你要把这个属性添加到哪个对象上,第二个是属性名,第三个是一个描述符对象。
如果该属性为数据属性,描述符对象就会包含四个属性:configurable(能否通过delete操作符删除),enumerable(能否通过for-in遍历属性),writable(能否修改属性)和value(属性值),前三个默认为false。如果该属性为访问器属性,描述符对象就会包含四个属性:configurable(能否通过delete操作符删除),enumerable(能否通过for-in遍历属性),get(在读取属性时调用的函数)和set(在写入属性时调用的函数),get和set默认为undefined。所以我们可以把数据设置为访问器属性,这样数据改变时就会触发get和set方法,我们可以通过这两个函数来实现对视图的更新。
实现数据的双向绑定
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
Observer
遍历data中的所有属性,同时通过递归的方式遍历这些属性的子属性,通过Object.defineProperty()将这些属性都定义为访问器属性,访问器属性自带get和set方法,我么通过get和set方法来监听数据变化。
Dep
我们需要消息订阅器来收集所有的订阅者,就好像是一个列表,当属性的get方法被触发时,需要判断是否要添加订阅者,如果需要就在列表中增加一个订阅者,当set方法被触发时就通知列表中所有的订阅者来做出响应。
Watcher
因为我们是在get函数中判断是否要添加订阅者的,要想把一个订阅者添加到列表中我们就需要在初始化这个订阅者时触发get函数,我们可以在Dep.target上缓存下订阅者,添加成功后再将其去掉就可以了。
Compile
compile负责初始化时的编译解析,遍历每一个结点,看哪些结点需要订阅者,也负责后续为订阅者绑定更新函数。
总结与理解
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
Object.defineProperty(obj, prop, descriptor)
obj
要在其上定义属性的对象。
prop
要定义或修改的属性的名称。
descriptor
将被定义或修改的属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

数据描述符和存取描述符均具有以下可选键值:
configurable
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
enumerable
当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
value
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable
当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
默认为 undefined。
set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
默认为 undefined。
描述符可同时具有的键值
configurable enumerable value writable get set
数据描述符 Yes Yes Yes Yes No No
存取描述符 Yes Yes No No Yes Yes
如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值