class Observe { constructor(obj) { Object.keys(obj).forEach(prop => { reactive(obj, prop, obj[prop]) }) } } function reactive(obj, prop) { let value = obj[prop] // 闭包绑定依赖 let dep = new Dep() Object.defineProperty(obj, prop, { configurable: true, enumerable: true, get() { //利用js单线程,在get时绑定订阅者 if (Dep.target) { // 绑定订阅者 dep.addSub(Dep.target) } return value }, set(newVal) { value = newVal // 更新时,触发订阅者更新 dep.notify() } }) // 对象监听 if (typeof value === 'object' && value !== null) { Object.keys(value).forEach(valueProp => { reactive(value, valueProp) }) } }
Dep
class Dep { constructor() { this.subs = [] } addSub(sub) { if (this.subs.indexOf(sub) === -1) { this.subs.push(sub) } } notify() { this.subs.forEach(sub => { const oldVal = sub.value sub.cb && sub.cb(sub.get(), oldVal) }) } }
Watcher
class Watcher { constructor(data, exp, cb) { this.data = data this.exp = exp this.cb = cb this.get() } get() { Dep.target = this this.value = (function calcValue(data, prop) { for (let i = 0, len = prop.length; i < len; i++ ) { data = data[prop[i]] } return data })(this.data, this.exp.split('.')) Dep.target = null return this.value } }
参考文档:https://cn.vuejs.org/v2/guide/reactivity.html
您可能感兴趣的文章: