// 數(shù)據(jù)監(jiān)聽(tīng)器
function Observer (obj, vm) {
if (!obj || typeof(obj) !== 'object') return
Object.keys(obj).forEach(function (key) {
defineReactive (vm, key, obj[key])
})
}
function defineReactive (obj, key, val) {
var dep = new Dep()
Observer(val) //監(jiān)聽(tīng)子屬性
Object.defineProperty(obj, key, {
get: function () {
if (Dep.target) {
dep.addSub(Dep.target)
}
return val
},
set: function (newVal) {
if (val === newVal) return
val = newVal
//作為發(fā)布者發(fā)布通知齐蔽,觸發(fā)訂閱者的更新函數(shù)
dep.notify()
}
})
}
// 消息訂閱器,收集訂閱者
function Dep () {
this.subs = []
}
Dep.prototype = {
addSub: function (sub) {
this.subs.push(sub)
},
notify: function () {
this.subs.forEach(function (sub) {
sub.update()
})
}
}
// 訂閱者
function Watcher (vm, node, name, type) {
Dep.target = this
this.name = name
this.node = node
this.vm = vm
this.type = type
this.update()
Dep.target = null
}
Watcher.prototype = {
update: function () {
this.get()
this.node[this.type] = this.value // 訂閱者執(zhí)行相應(yīng)的操作
},
// 獲取data的屬性值
get: function () {
this.value = this.vm[this.name]
}
}