observer
递归遍历$data
然后用Object.defineProperty()设置数据的setter和getter
if(data && typeof data === 'object'){
Object.keys(data).forEach(key => {
this.defineReactive(data,key,data[key])
})
}
defineReactive(obj,key,value){
this.observe(value)
const dep = new Dep()//实现关联
Object.defineProperty(obj,key,{
enumerable: true,
configurable: false,
get(){
//订阅数据变化的时候往dep中添加观察者
Dep.target && dep.addSub(Dep.target)
return value;
},
set:(newVal) => {
this.observe(newVal)//箭头函数没有this指向所以会往上找最终指向Observer
if(newVal !== value){
value = newVal
}
//通知Dep有变化
Dep.notify
}
})
}
Dep(数据劫持前一刻关联,get前添加挂载的观察者,set后用dep通知有变化)
负责收集观察者和通知观察者更新
class Dep{
constructor(){
this.subs = []
}
//收集观察者
addSub(watcher){
this.subs.push(watcher)
}
//通知观察者更新
notify(){
this.subs.forEach(w => w.update())
}
Watcher(Upater更新数据前一刻绑定)
class Watcher{
constructor(vm,expr,callback){
this.vm = vm;
this.expr = expr
this.callback = callback
//先把旧的值保存
this.oldVal = this.getOldVal()
}
update(){
const newVal = compileUtil.getValue(this.expr,this.vm)
if(newVal !== this.oldVal){
this.cb(newVal)
}
}
getOldVal(){
Dep.target = this//挂载
const oldVal = compileUtil.getValue(this.expr,this.vm)
Dep.target = null//置空
return oldVal
}
}