具体可以看bilibili的视频https://www.bilibili.com/video/BV15D4y1o73Z
源码可以自己下载,和视频基本一样
下载地址:https://github.com/superBiuBiuMan/vue-write-self
获取旧值表达式为以下
getOldValue(){
Dep.target = this;
const oldvalue = compileUtil.getValue(this.expr,this.vm.$data);
Dep.target = null;
return oldValue;
}
defineProperty为data当中的每一个属性添加了set和get方法,也就是说compileUtil.getValue()之后就会添加watcher的问题Dep.target = null取消呢?
person.name的时候,我们必须要返回上一次获取的值作为vm.$data,才可以循环获取到最终的name值,老师写的vm.$data不会返回上一次获取到的值,所以就会导致报错 /*设置表达式的值*/
setVal(expr,vm,inputValue){
//当设置的值为person.fav这种多层对象的时候,会报错
//expr.split(".").reduce((preData,currentValue)=>{
// console.log(preData)
// preData[currentValue] = inputValue;
//},vm.$data)
//所以下面是修复
expr.split(".").reduce((preData,currentValueKey)=>{
if(Object.prototype.toString.call(preData[currentValueKey]) === '[object Object]'){
return preData[currentValueKey];
}else{
preData[currentValueKey] = inputValue;
}
},vm.$data)
},
vue通过数据劫持和发布者订阅者模式,通过Object.defineProperty()当中的setter和getter来劫持数据变动,从而达到在数据变动的时候通知相应的dep去执行对应的watcher
我们在创建vue则会执行模板的解析,也就是compile,在解析编译时候,为会为每一个使用到的字段创建相应的watcher,并添加到对应的Dep当中,在我们通过Observer劫持监听所有属性的时候,是通过Object.defineProperty的setter和getter来实现的,当我们更新数据的时候,会通知dep去执行里面的watcher

