SOURCE

// 参考:https://blog.csdn.net/howgod/article/details/95135265
// // observe、Watch、Dep
class Vue {
    constructor(options) {
        this.data = options.data;
        observe()
        new Watcher();
    }
}

// function render () {
//   console.log('模拟视图渲染')
// }
// let data = {
//   name: '浪里行舟',
//   location: { x: 100, y: 100 }
// }
// observe(data)
function observe (obj) {	
  // 判断类型	
  if (!obj || typeof obj !== 'object') {	
    return	
  }	
  Object.keys(obj).forEach(key => {	
    defineReactive(obj, key, obj[key])	
  })	
  function defineReactive (obj, key, value) {	
    observe(value)  // 递归子属性	
    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 value	
      },	
      set: function reactiveSetter (newVal) {	
        observe(newVal) //如果赋值是一个对象,也要递归子属性	
        if (newVal !== value) {	
          console.log('set', newVal) // 监听	
          render()	
          value = newVal	
     // 执行 watcher 的 update 方法	
          dp.notify() //新增	
        }	
      }	
    })	
  }	
}
// data.location = {
//   x: 1000,
//   y: 1000
// } //set {x: 1000,y: 1000} 模拟视图渲染
// data.name // get 浪里行舟


// Dep的简单实现

class Dep {	
    constructor () {	
        /* 用来存放Watcher对象的数组 */	
        this.subs = [];	
    }	
    /* 在subs中添加一个Watcher对象 */	
    addSub (sub) {	
        this.subs.push(sub);	
    }	
    /* 通知所有Watcher对象更新视图 */	
    notify () {	
        this.subs.forEach((sub) => {	
            sub.update();	
        })	
    }	
}

// 所以当需要依赖收集的时候调用 addSub,当需要派发更新的时候调用 notify。调用也很简单:
// let dp = new Dep()	
// dp.addSub(() => {	
//     console.log('emit here')	
// })	
// dp.notify()

// Watcher的简单实现
class 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]	
   // 我们定义一个 cb 函数,这个函数用来模拟视图更新,调用它即代表更新视图	
    this.cb(this.value)	
  }	
}
console 命令行工具 X clear

                    
>
console