JSFiddle - React, Tailwind, and code Playground

by ruirui

HTML

<div>
Vue 数据绑定二
</div>
<div>
请打开控制台查看
</div>

JavaScript

function Observer(data) {
  this.data = data;
  this.makeObserver(data);
  this.eventsBus = new Event();
}

Observer.prototype.makeObserver = function(data) {
  for(var i in data) {
    if(data.hasOwnProperty(i)) {
      if(typeof data[i] === 'object') {
        new Observer(data[i]);
      }
      this.getset(i, data[i]);
    }
  }
}

Observer.prototype.getset = function(i, value) {
  let val = value;
  let that = this;
  Object.defineProperty(this.data, i, {
    configurable: true,
    enumerable: true,
    get: function () {
      console.log('你访问了' + i);
      return val;
    },
    set: function (newval) {
      console.log('你设置了' + i + ',新的值为' + newval);
      if(typeof newval === 'object') { //对新对象也进行监听
        new Observer(newval);
      }
      if(newval !== val) {
        // 触发
        that.eventsBus.emit(i, newval);
        val = newval;
      }
    }
  })
}


function Event() {
  this.events = {};
}
Event.prototype.on = function (attr, callback) {
  if (this.events[attr]){
    this.events[attr].push(callback);
  } else {
    this.events[attr] = [callback];
  }
}
Event.prototype.emit = function (attr, newval) {
  console.log(this.events); // 每一层的event都是独立的,深层对象属性触发的时候可以看出this.events里为空。
  for(var item in this.events) {
    if(item === attr) {
      this.events[attr].forEach(function(item) {
        item(newval);
      })
    }
  }
}

Observer.prototype.$watch = function (attr,callback){
  // 注册一个监听事件
  this.eventsBus.on(attr, callback);
}

let app1 = new Observer({
  age: 25,
  name: {
    firstName: 'rui',
    lastName: 'sun'
  }
})
app1.$watch('age', function(age) {
  console.log(`我的年纪变了,现在已经是:${age}岁了`)
});
app1.$watch('lastName', function(lastName) {
  console.log(`我的名字变了,现在已经是:${lastName}了`)
});

console.log(app1.data.age = 100);
console.log(app1.data.name.lastName = 'season');