| // arrayMethods是重写了数组方法的对象 const arrayKeys = Object.getOwnPropertyNames(arrayMethods) // 监听开关 export let shouldObserve: boolean = true export class Observer { value: any; // 需要被转化成响应式数据的对象 dep: Dep; // 重点!用于收集数组的依赖,只有数组会通过这个Dep通过watcher。 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 // 当前Observer实例被挂到数据的'__ob__',也标识了这个数据成为响应式数据 def(value, '__ob__', this) if (Array.isArray(value)) { if (hasProto) { // 如果浏览器支持__proto__,直接将arrayMethods挂到value.__proto__上 protoAugment(value, arrayMethods) } else { // 不支持__proto__,则将arrayMethods的方法直接加到value上 copyAugment(value, arrayMethods, arrayKeys) } // 进一步将数组中元素也变成响应式数据 this.observeArray(value) } else { // 非数组,则是Object this.walk(value) } } walk (obj: Object) { const keys = Object.keys(obj) for (let i = 0; i < keys.length; i++) { defineReactive(obj, keys[i]) } } observeArray (items: Array<any>) { for (let i = 0, l = items.length; i < l; i++) { observe(items[i]) } } } function protoAugment (target, src: Object) { /* eslint-disable no-proto */ target.__proto__ = src /* eslint-enable no-proto */ } function copyAugment (target: Object, src: Object, keys: Array<string>) { for (let i = 0, l = keys.length; i < l; i++) { const key = keys[i] def(target, key, src[key]) } } // 如果value有__ob__,说明已经是响应式数据,无需处理,否则需要通过Observer类进行处理 export function observe (value: any, asRootData: ?boolean): Observer | void { if (!isObject(value) || value instanceof VNode) { return } let ob: Observer | void 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 ) { ob = new Observer(value) } if (asRootData && ob) { ob.vmCount++ } return ob } // 封装Object.defineProperty export function defineReactive ( obj: Object, key: string, val: any, customSetter?: ?Function, shallow?: boolean ) { // defineReactive方法内部的dep,用于收集当前Key的依赖 const dep = new Dep() const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return } // 保存原有getter setter const getter = property && property.get const setter = property && property.set if ((!getter || setter) && arguments.length === 2) { val = obj[key] } // 如果val是复杂对象,则转为响应式数据并取出他的'__ob__'上的Observer实例 let childOb = !shallow && observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { const value = getter ? getter.call(obj) : val // 如果有正在处理的watcher if (Dep.target) { // 当前key的dep收集watcher dep.depend() // val的dep收集watcher if (childOb) { childOb.dep.depend() // 最新值如果是数组,数组中的复杂对象也需要收集watcher if (Array.isArray(value)) { dependArray(value) } } } return value }, set: function reactiveSetter (newVal) { // 读取旧值 const value = getter ? getter.call(obj) : val // 对比新旧值,无变化则return,无需通知 if (newVal === value || (newVal !== newVal && value !== value)) { return } if (process.env.NODE_ENV !== 'production' && customSetter) { customSetter() } if (getter && !setter) return if (setter) { setter.call(obj, newVal) } else { val = newVal } // 将新值处理成响应式数据 childOb = !shallow && observe(newVal) // 值发生变化,通知当前key的dep,dep再通知收集的所有watcher dep.notify() } }) } // 递归,使每层每个复杂对象都能被当前watcher订阅 function dependArray (value: Array<any>) { for (let e, i = 0, l = value.length; i < l; i++) { e = value[i] e && e.__ob__ && e.__ob__.dep.depend() if (Array.isArray(e)) { dependArray(e) } } } |