响应式原理-Observer
本篇将详细讲解,当在 observe 中 new Observer 创建 observer 实例的过程中是如何实现数据的响应式的。
/**
* Observer class that is attached to each observed
* object. Once attached, the observer converts the target
* object's property keys into getter/setters that
* collect dependencies and dispatch updates.
*/
export class Observer {
// 通常习惯于将类的属性下载最前,为了方便代码维护及阅读
// 观测对象
value: any;
// 依赖对象
dep: Dep;
// 实例计数器
vmCount: number; // number of vms that have this object as root $data
constructor (value: any) {
this.value = value
this.dep = new Dep()
// 初始化实例的 vmCount 为 0
this.vmCount = 0
// 将实例挂载到观察对象的 __ob__ 属性,在入口函数中将通过这个属性判断对象是否已经作过数据响应式处理
// def 这个方法就是通过 Object.defineProperty 这个方法给对象添加一个属性,并给属性设置响应的属性
def(value, '__ob__', this)
// 数组的响应式处理
if (Array.isArray(value)) {
if (hasProto) {
protoAugment(value, arrayMethods)
} else {
copyAugment(value, arrayMethods, arrayKeys)
}
// 为数组的每一个对象创建一个 observer 实例
this.observeArray(value)
} else {
// 遍历对象中的每一个属性,转换成 setter/getter
this.walk(value)
}
}
/**
* Walk through all properties and convert them into
* getter/setters. This method should only be called when
* value type is Object.
*/
walk (obj: Object) {
// 获取观察对象中的每一个属性
const keys = Object.keys(obj)
// 遍历每一个属性,设置为响应式数据
for (let i = 0; i < keys.length; i++) {
// 把对象的属性转换成 getter/setter
// 在转换的时候还会做一些其他的处理,比如收集依赖,发送通知
defineReactive(obj, keys[i])
}
}
/**
* Observe a list of Array items.
*/
// 对数组做响应式的处理
observeArray (items: Array<any>) {
for (let i = 0, l = items.length; i < l; i++) {
observe(items[i])
}
}
}
Observer 这个类的作用非常直白,就是对数组或者对象做响应式处理。