我们打开文件 src/core/observer/index.js
,找到定义Observer
函数的代码:
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
// 用来给数据添加Dep依赖
this.dep = new Dep()
this.vmCount = 0
def(value, '__ob__', this)
if (Array.isArray(value)) {
if (hasProto) {
protoAugment(value, arrayMethods)
} else {
copyAugment(value, arrayMethods, arrayKeys)
}
this.observeArray(value)
} else {
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++) {
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])
}
}
}
constructor
constructor (value: any) {
this.value = value
// 用来给数据添加Dep依赖
this.dep = new Dep()
this.vmCount = 0
def(value, '__ob__', this)
if (Array.isArray(value)) {
if (hasProto) {
protoAugment(value, arrayMethods)
} else {
copyAugment(value, arrayMethods, arrayKeys)
}
this.observeArray(value)
} else {
this.walk(value)
}
}
首先是给 value
对象添加了 'ob'属性。
然后判断value
是否是数组,如果是数组的话,就对数组进行处理,然后在调用observeArray
函数对value
进行处理。
arrayMethods有如下具体方法,这些方法就是vue给我们实现了双向绑定[ 'push','pop', 'shift', 'unshift', 'splice','sort', 'reverse']
observeArray
代码如下:
/**
* Observe a list of Array items.
*/
observeArray (items: Array<any>) {
for (let i = 0, l = items.length; i < l; i++) {
observe(items[i])
}
}
}
可以看到对数组进行了遍历监听,这就是为什么Object.defineProperty
是不支持数组监听的,但是vue里面数组的改变还是一个响应式的特性。
接下来我们看看walk
的代码,比较简单。
walk (obj: Object) {
const keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i])
}
}
可以看到首先是获取了所有的keys
,然后一一进行监听。
网友评论