// 如果value中存在__ob__属性,并且__ob__是Observer,则直接将value.__ob__赋值给ob
if (hasOwn(value, ‘ob’) && value.ob instanceof Observer) {
ob = value.ob
} else if (
shouldObserve &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
// 并且当前是浏览器环境
// 并且value是一个数组或者是’[object Object]’
// 并且value是可扩展的(可以在它上面添加新的属性)
// 并且value不是Vue实例
// 创建一个Observer对象,并赋值给ob
ob = new Observer(value)
}
// 如果处理的是根数据并且存在ob,则ob.vmCount++
if (asRootData && ob) {
ob.vmCount++
}
return ob
}
==========================================================================
对应源码src/core/observer/index.js的 55 行
-
constructor()方法,初始化数据,并改变数组当前对象的原型属性
-
walk()方法为对象做响应式处理
-
observeArray()方法为数组做响应式处理
export class Observer {
// 数据对象
value: any;
// 依赖对象
dep: Dep;
// 实例计数器
// 以该对象在根$data的vms数
vmCount: number; // number of vms that have this object as root $data
// 构造函数,初始化数据
constructor (value: any) {
this.value = value
this.dep = new Dep()
this.vmCount = 0
// 将实例挂载到观察对象的__ob__属性
def(value, ‘ob’, this)
// 如果观察对象是一个数组,将数组转换为响应式数据
if (Array.isArray(value)) {
if (hasProto) {
protoAugment(value, arrayMethods) // 改变数组当前对象的原型属性
} else {
copyAugment(value, arrayMethods, arrayKeys)// 改变数组当前对象的原型属性
}
// 为数组中的每一个对象元素创建一个observer实例
this.observeArray(value)
} else {
// 遍历对象中的每一个属性,转换成getter/setter
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) {
for (let i = 0, l = items.length; i < l; i++) {
observe(items[i])
}
}
}
对应源码src/core/observer/index.js的 135 行
-
为一个对象定义一个响应式的属性,每一个属性对应一个 dep 对象
-
如果该属性的值是对象,继续调用 observe
-
如果给属性赋的新值是一个对象,继续调用 observe
-
如果数据更新发送通知
// 在对象上定义响应式属性
export function defineReactive (
obj: Object,
key: string,
val: any,
customSetter?: ?Function,
shallow?: boolean
) {
// 创建依赖对象实例,其作用是为当前属性(key)收集依赖
const dep = new Dep()
// 获取obj对象的属性描述符
const property = Object.getOwnPropertyDescriptor(obj, key)
// 当且仅当该属性的 configurable 键值为 true 时
// 该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
// 如果存在属性描述符,并且configurable为false,即不可被转换为响应式数据,则不继续往下执行
if (propert