实现思路: 数据劫持+观察者模式
- 首先通过调用
Object.defineProperty
将属性进行递归劫持 - 然后每次生成一个
getter
和setter
,通过自身的dep
属性来存放对应的watcher
,这步叫做依赖收集
- 最后当
属性
发生变化后会通知自己的watcher
去更新
。 - 注意一点:数组的方法需要重写,且监听不到数组的
长度改变
及下标的值的改变
。长度发生改变通过splice
方法来代替,下标值改变用vue官方提供的Vue.set(arr,index,value)
代码实现:
class Observer {
constructor(value) {
this.walk(value)
}
walk(data) {
for(let key in data) {
defineActive(data,key,data[key])
}
}
}
function defineActive(data,key,value) {
// 递归劫持
observe(value)
Object.defineProperty(data,key,{
get(){
console.log('获取值');
return value
},
set(newVal){
if(newVal == value) return;
console.log('设置新值');
value = newVal
}
})
}
function observe(value){
if(Object.prototype.toString.call(value) == '[object Object]' || Array.isArray(value)) {
return new Observer(value)
}
}