Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新。

https://juejin.cn/post/6844903479044112391

如何实现的

Object.defineProperty

  1. Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

用例

  1. let car = {}
  2. let val = 3000
  3. Object.defineProperty(car, 'price', {
  4. get(){
  5. console.log('price属性被读取了')
  6. return val
  7. },
  8. set(newVal){
  9. console.log('price属性被修改了')
  10. val = newVal
  11. }
  12. })

监听了对象 car 的键 price,所以当 price 变化时,能够监听这个动作。其他的 key 没有监听,就不会捕获变化。
image.png
所以监听到了 price 变化,没有监听到 name 变化。
Vue 就是在定义属性的时候循环监听了 对象所有的 key,实现双向绑定

实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。
image.png