实现Vue响应式原理 之 observer.js部分
结构介绍
Observer功能
Observer作用是数据劫持,也就是监听data中属性的变化并做出处理。
1.负责把 data 选项中的属性转换成响应式数据(getter/setter)
2.data 中的某个属性也是对象,把该属性转换成响应式数据
3.数据变化发送通知(结合观察者模式来实现)
Observer结构
代码实现
observer.js
// 负责数据劫持
// 把 $data 中的成员转换成 getter/setter
class Observer {
constructor(data) {
this.walk(data)
}
// 1. 判断数据是否是对象,如果不是对象返回,如果是空值,也返回
// 1.1. 如果是对象,遍历对象的所有属性,设置为 getter/setter
walk(data) {
if (!data || typeof data !== 'object') {
return
}
// 2. 遍历 data 的所有成员
Object.keys(data).forEach(key => {
this.defineReactive(data, key, data[key])
})
}
// 定义响应式成员
defineReactive(data, key, val) {
const that = this
// 如果 val 是对象,继续设置它下面的成员为响应式数据
this.walk(val)
Object.defineProperty(data, key, {
configurable: true,
enumerable: true,
get() {
return val // return val而不是data[key],因为returndata[key]会触发get方法,发生死递归,造成堆栈溢出
},
set(newValue) {
if (newValue === val) {
return
}
// 如果 newValue 是对象,设置 newValue 的成员为响应式
that.walk(newValue) // set 内部的this指向data对象
val = newValue
}
})
}
}
总结
Observer对象的核心作用是把data中的属性都转化为响应式数据,也就是getter/setter
如果data中的某个属性是对象,那么也会把这个对象中的属性转化为响应式数据
如果data中的某个属性重新赋值为一个新对象时,那么也会把这个对象中的属性转化为响应式数据