class Observe {
constructor (data) {
if (!data || typeof data !== 'object') return
this.data = data
this.walk()
}
walk () {
Object.keys(this.data).forEach(function(val, key){
this.propretyRactive(this.data,val,this.data[val])
}, this)
}
propretyRactive(data, key, val){
//为了保证每层的值都能添加getter,setter方法进行回调
new Observe(val)
var dep = new Dep()
Object.defineProperty(data, key, {
get (){
if (Dep.target){
dep.addSub(Dep.target)
}
return val
},
set (newVal) {
if (newVal !== val) {
val = newVal
// 为新值添加getter,setter方法
new Observe(val)
dep.notify()
}
}
})
}
}
//发布者类
class Dep {
constructor () {
this.subs = []
}
addSub (sub) {
if (!this.subs.includes(sub)){
this.subs.push(sub)
}
}
notify () {
this.subs.forEach(function(val){
val.update()
})
}
}
Dep.target = null
//订阅者类
class Watcher {
constructor (vm, keys, updateCb) {
this.vm = vm
this.keys = keys
this.updateCb = updateCb
this.value = this.get()
}
get () {
Dep.target = this
var value = this.vm.data
let key = this.keys.split('.')
//隐式调用getter方法。从而将订阅者添加到发布者的通知列表
key.forEach(_key=>{
value = value[_key]
})
Dep.target = null
return value
}
update () {
let newVal = this.get()
if (newVal !== this.value){
this.value = newVal
this.updateCb.call(this.vm)
}
}
}
var data = {
test: 1,
testObj: {
tb1: 1
}
}
var vm = new Observe(data)
new Watcher(vm, 'test', function(){
console.dir('test已更新')
})
new Watcher(vm, 'testObj.tb1', function(){
console.dir('testObj.tb1已更新')
})
data.testObj.tb1 = 2
网友评论