简单实现Vue数据响应式 发表于 2018-03-09 | 分类于 Demo | 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980function observe(obj) { // 判断类型 if (!obj || typeof obj !== 'object') { return } Object.keys(obj).forEach(key => { defineReactive(obj, key, obj[key]) })}class Dep { constructor() { this.subs = [] } // 添加依赖 addSub(sub) { this.subs.push(sub) } // 更新 notify() { this.subs.forEach(sub => { sub.update() }) }}// 全局属性,通过该属性配置 WatcherDep.target = nullclass Watcher { constructor(obj, key, cb) { // 将 Dep.target 指向自己 // 然后触发属性的 getter 添加监听 // 最后将 Dep.target 置空 Dep.target = this this.cb = cb this.obj = obj this.key = key this.value = obj[key] Dep.target = null } update() { // 获得新值 this.value = this.obj[this.key] // 调用 update 方法更新 Dom this.cb(this.value) }}function defineReactive(obj, key, val) { // 递归子属性 observe(val) let dp = new Dep() Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { console.log('get value') // 将 Watcher 添加到订阅 if (Dep.target) { dp.addSub(Dep.target) } return val }, set: function reactiveSetter(newVal) { console.log('change value') val = newVal // 执行 watcher 的 update 方法 dp.notify() } })}var data = { name: 'aaa' }observe(data)function update(value) { document.querySelector('div').innerText = value}// 模拟解析到 `{{name}}` 触发的操作new Watcher(data, 'name', update)data.name = 'bbb' 坚持原创技术分享,您的支持将鼓励我继续创作! 赏 微信打赏 支付宝打赏