class Dep {
constructor () {
// 定义一个收集对应属性依赖的容器
this.subs = []
}
// 收集依赖的方法
addSub () {
// Dep.target是个全局变量,用于存储当前的一个watcher
this.subs.push(Dep.target)
}
// set方法被触发时会通知依赖
notify () {
for (let i = 1; i < this.subs.length; i++) {
this.subs[i].cb()
}
}
}
Dep.target = null
class Watch {
constructor (exp, cb) {
this.exp = exp
this.cb = cb
// 将Watch实例赋给全局变量Dep.target,这样get中就能拿到它了
Dep.target = this
data[exp]
}
}
function defineReactive (data, key, val) {
observer()
let dep = new Dep() // 新增:这样每个属性就能对应一个Dep实例了
Object.defineProperty(data, key, {
configurable: true,
enumerable: true,
get () {
dep.addSub() // 新增:get触发时会触发addSub来收集当前的Dep.target,即watcher
return val
},
set (newVal) {
if (newVal === val) {
return
} else {
data[key] = newVal
observer(newVal)
dep.notify() // 新增:通知对应的依赖
}
}
})
}
// 定义一个类供传入监听数据
class Observer {
constructor(data) {
let keys = Object.keys(data)
for (let i = 0; i < keys.length; i++) {
defineReactive(data, keys[i], data[keys[i]])
}
}
}
// 递归判断
function observer (data) {
if (Object.prototype.toString.call(data) === '[object Object]') {
new Observer(data)
} else {
return data
}
}
// ================
// 需要劫持的数据
let data = {
a: 1,
b: {
c: 3
}
}
// 劫持数据data
observer(data)
// 监听订阅数据data的属性
new Watch('a', () => {
alert(1)
})
new Watch('a', () => {
alert(2)
})
new Watch('b.c', () => {
alert(3)
})
data.a = 33
console.log(data,'data')
console