JSFiddle - React, Tailwind, and code Playground

HTML

<div id="app">
  <h1>{{title}}</h1>
  <input v-model="name">
  <h2>{{name}}</h2>
  <h3>count: <span>{{count}}</span></h3>
  <button v-on:click="clickMe">clickMe</button>
</div>

CSS

#app {
  text-align: center;
}

JavaScript

class Dep {
	constructor() {
		this.subs = [];
	}

	addSub(watcher) {
		this.subs.push(watcher);
	}

	notify() {
		this.subs.forEach(watcher => {
			watcher.update();
		});
	}
}

Dep.target = null;

class Observer {
	constructor(data) {
		this.data = data;
		this.walk();
	}

	walk() {
		Object.keys(this.data).forEach(key => {
			this.defineReactive(this.data, key, this.data[key]);
		});
	}

	defineReactive(data, key, value) {
		const dep = new Dep();

		if ( value && typeof value === 'object' ) {
			new Observer(value);
		}

		Object.defineProperty(data, key, {
			enumerable: true,
			configurable: true,
			get() {
				if (Dep.target) {
					dep.addSub(Dep.target);
				}
				return value;
			},
			set(newVal) {
				if (newVal === value) {
					return false;
				}
				value = newVal;
				dep.notify();
			}
		});
	}
}

class Watcher {
	constructor(vm, exp, cb) {
		this.cb = cb;
		this.vm = vm;
		this.exp = exp;

		// 将自己添加到订阅器的操作
		this.value = this.getValue();
	}

	update() {
		const value = this.vm.data[this.exp];
		const oldValue = this.value;
		if (value !== oldValue) {
			this.value = value;
			this.cb.call(this.vm, value, oldValue);
		}
	}

	getValue() {
		Dep.target = this;
		const value = this.vm.data[this.exp];
		Dep.target = null;
		return value;
	}
}

class Compile {
	constructor(el, vm) {
		this.vm = vm;
		this.el = document.querySelector(el);
		this.fragment = null;
		this.init();
	}

	init() {
		if (this.el) {
			this.fragment = this.nodeToFragment();
			this.compileElement(this.fragment);
			this.el.appendChild(this.fragment);
		}
	}

	nodeToFragment() {
		const fragment = document.createDocumentFragment();
		let child = this.el.firstChild;

		while (child) {
			fragment.appendChild(child);
			child = this.el.firstChild
		}
		return fragment;
	}

	compileElement(fragment) {
		const childNodes = fragment.childNodes;
		[].slice.call(childNodes).forEach((node) => {
			const reg = /\{\{(.*)\}\}/;
			const text = node.textContent;

			if...