思维导图
前言
上一节Vue 源码初探(五)对象异步更新nextTick()我们处理了对象频繁修改值,把多次操作进行合并处理,其中就是把依赖信息先收集起来放到微任务中一起执行
正文
给引用类型创建dep
class Observer {
constructor(data) {
//给每一个监测的对象添加一个__ob__的属性指向自己,可以用来判断当前对象是否已经监测过了。
// data.__ob__ = this
//这个属性不能在循环的时候被遍历到
//希望给一个上新增一个属性,也能更新视图。
// {name: '小明', age: '10'}.dep => watcher
this.dep = new Dep()
Object.defineProperty(data, '__ob__', {
value: this,
enumerable: false
})
}
}
引用属性值、数组递归收集依赖(watcher)
Object.defineProperty(data, key, {
get() {
if (Dep.target) { //dep.target 现在保存着watcher
dep.depend()
if (childOb) { //取属性的时候 会对对应的值(对象本身和数组)进行依赖收集
childOb.dep.depend() //让数组和对象也记住当前的watcher
if(Array.isArray(value)){
dependArray(value)
}
}
}
return value
}
})
触发更新
const ob = this.__ob__
ob.dep.notify() //触发页面更新
小结
- 默认
vue在初始化的时候,会对每一个属性进行劫持,增加dep属性,当取值的时候会进行依赖收集 - 默认还会对属性值是(对象和数组本身进行增加
dep属性)进行依赖收集 - 如果是属性变化 触发属性对应的
dep去更新 - 如果是数组更新,触发数组本身的
dep进行更新 - 如果取值的时候是数组还要让数组中的对象类型也进行依赖收集 (递归依赖收集)
- 如果数组里面放对象,默认对象里面的属性是会进行依赖收集的,因为在取值的时候会进行
JSON.stringify操作。