JSFiddle - React, Tailwind, and code Playground

by liuyj

HTML

<div id="app">hhh</div>
<button onclick="setApp()">setName</button>

Babel + JSX

const ob = function (data) {
  // 无new构造
  if (!(this instanceof ob)) {
    return new ob(data);
  }
  // 设定观察者列表
  let observerList = [];

  // 暴露添加观察者方法
  this.addOb = function (fn) {
    observerList.push(fn);
  }

  // 遍历属性,通过defineProperty来对属性变化做监听
  for (let key in data) {
    let value = data[key];
    Object.defineProperty(data, key, {
      enumerable:true, // 枚举
      get () {
        return value;
      },
      set (newVal) {
        value = newVal;
        observerList.forEach((el)=>{
          el(newVal);
        })
      }
    })
  }
}

const render = (text) => {
  document.getElementById('app').innerHTML = '<p>'+ text +'</p>'
}

let testObj = {
  name: 'liu'
};

const vm = (data) => {
  render(testObj.name);
  let newOb = ob(data);
  newOb.addOb(function () {
    render(data.name);
  })
};

vm(testObj);

function setApp() {
  testObj.name = 'hello';
}