class Vue {
constructor(options) {
this.$el = options.el
this.$data = options.data
if (this.$el) {
new Observer(this.$data)
new Compiler(this.$el, this)
}
}
}
class Observer {
constructor(data) {
this.observer(data)
}
observer(data) {
if (typeof data === 'object' && data != null) {
for (let key in data) {
this.defineReactive(data, key, data[key])
}
}
}
defineReactive(obj, key, value) {
this.observer(value)
let dep = new Dep()
Object.defineProperty(obj, key, {
get() {
Dep.target && dep.addSub(Dep.target)
return value
},
set(newVal) {
if (newVal != value) {
this.observer(newVal)
value = newVal
dep.notify()
}
}
})
}
}
class Watcher {
constructor(vm, expr, cb) {
this.vm = vm
this.expr = expr
this.cb = cb
ths.oldVal = this.get()
}
get() {
Dep.target = this
let value = CompilerUnit.getVal(this.vm, this.expr)
Dep.target = null
return value
}
updata() {
let newVal = CompilerUnit.getVal(this.vm, this.expr)
if (newVal != this.oldVal) {
this.cb(newVal)
}
}
}
class Dep {
constructor() {
this.subs = []
}
addSub(watcher) {
this.subs.push(watcher)
}
notify() {
this.subs.forEach(watcher => watcher.updata())
}
}
console