笔记
- vue2响应系统的实现核心是借助了
Object.defineProperty
这个api。它的工作流程可以概括为:在getter中收集依赖,在setter中触发依赖。 Object.defineProperty
的缺陷:
- 无法监听到新添加的Obj属性
- 无法监听到删除的Obj属性
vue2的解决方法是使用了vm.$set
与vm.$delete
- Data、Observer、Dep、Wacher之间的关系
- Data通过Observer转换成了getter/setter的形式来追踪变化。
- 当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。
- 当数据发生了变化时,会触发setter,从而向Dep中的依赖(Watcher)发送通知。
- Watcher接收到通知后,会向外界发送通知,变化通知到外界后可能会触发视图更新,也有可能触发用户的某个回调函数等。
- Array的响应式实现是创建了一个Obj,这个Obj的key为Array的方法,并将Obj的key用
Object.defineProperty
全部包装了一遍,当用户在Vue.data中创建数组时,就用这个对象覆盖,从而实现监听效果。
const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto);
[
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
].forEach(function (method) {
// 缓存原始方法
const original = arrayProto[method]
Object.defineProperty(arrayMethods, method, {
value: function mutator (...args) {
console.log('我监听到了',method)
return original.apply(this, args)
},
enumerable: false,
writable: true,
configurable: true
})
})
arrayMethods.push(4)
故此响应式Array是无法监听到obj[0] = 1 这种变化的。