src\core\observer\index.js
export class Observer { }
Observer这个类会被附加在每一个可观察对象上
export function defineReactive ( }
利用 Object.defineProperty 函数作用于对象属性的值,进行取值和赋值操作时的拦截和处理
数组对象中的每一个key设置dep,为什么在Observer里声明dep?(给每个对象加一个dep呢)
1.obeject里面有新增或者删除属性
2.array中有变更方法
都需要dep去通知watcher去检测变化 ,然后做更新(diff算法),只更新修改的部分
(会触发setter方法,告诉watcher有依赖变化,watcher收到信息,重新渲染dom,实现页面数据更新)
拦截操作做了什么?
这里是引用
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 // 数组对象中的每一个key设置dep,为什么在Observer里声明dep?(给每个对象加一个dep呢) this.dep = new Dep() this.vmCount = 0 //设置__ob__属性,引用当前Observer实例 def(value, '__ob__', this) //如果是数据就替换数组对象的原型 if (Array.isArray(value) ) { if (hasProto) { // 覆盖原型的方法 // 把覆盖过得arrayMethods直接替换掉。这个数组以后就会通知了 // 覆盖完7个数组方法之后,会覆盖到数组实例上 protoAugment(value, arrayMethods) } else { copyAugment(value, arrayMethods, arrayKeys) } // 如果数组里面元素是对象还需要进行响应式处理,数组本身需要处理,数组里含有对象也需要进行处理 this.observeArray(value) } else { //对象的话直接处理 this.walk(value) } }
export function defineReactive ( //dep和key一一对应 const dep = new Dep() //属性拦截核心代码,只要是对象类型,均会返回childob (这里指val) let childOb = !shallow && observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { //获取key对应的值 const value = getter ? getter.call(obj) : val //如果存在依赖 if (Dep.target) { //收集依赖 dep.depend() if (childOb) { //如果存子ob,子ob也收集依赖 childOb.dep.depend() if (Array.isArray(value)) { dependArray(value) } } } return value }, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val 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) //通知更新,会调用watcher.js方法进行更新 dep.notify() } }