Vue内部经过Object.defineProperty方法属性拦截的方式,把data对象里每一个数据的读写转化成getter/setter,当数据变化时通知视图更新。html
具体说一下Object.defineProperty:面试
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。bash
Object.defineProperty(obj, prop, descriptor)
obj:要在其上定义属性的对象。
prop:要定义或修改的属性的名称。
descriptor:将被定义或修改的属性描述符。
复制代码
Object.defineProperty()具体实现:markdown
let hr={ skill:'', experience:'' } Object.defineProperty(hr, 'skill', { get(){ console.log('必备技能:') return '画大饼' }, set(newVal){ console.log('加分项:') } }) //读: console.log(hr.skill) //写: hr.skill='吹牛皮' 复制代码
控制台打印 必备技能: 画大饼 经验要求: "吹牛皮" 复制代码
如今已经能够检测到数据的读和写,而后就须要通知视图的更新了.oop
这里是典型的发布订阅模式,在这个模式下:数据是发布者(Observer),依赖对象是订阅者(Watcher),他们须要一个中间人来传递,那就是订阅器(Dep)。post
总结:实现数据的双向绑定,首先要对数据进行劫持监听,因此咱们须要设置一个监听器Observer,用来监听全部属性。若是属性发生变化了,就须要告诉订阅者Watcher看是否须要更新。由于订阅者Watcher是有不少个,因此咱们须要有一个消息订阅器Dep来专门收集这些订阅者,而后在监听器Observer和订阅者Watcher之间进行统一管理。spa
Object.defineProperty() -MDN双向绑定