<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script>
class watcher {
constructor(vm, exp, cb) {
this.vm = vm;
this.exp = exp;
this.cb = cb;
this.value = this.get();
}
update() {
var value = this.vm.data[this.exp];
if (value == this.value) {
return false;
} else {
this.cb(this.vm, this.exp,value,this.value);
}
}
get() {
Dep.target = this;
var value = this.vm.data[this.exp];
Dep.target = null;
return value;
}
}
class Dep {
constructor(list = []) {
this.list = list;
}
addWatch(item) {
this.list.push(item);
}
notify() {
this.list.forEach(item => item.update());
}
}
function defineReactive(vm,data, key, val) {
observe(vm,val);
let dep = new Dep();
vm._oberve=Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get() {
console.log('get', key);
if (Dep.target) {
dep.addWatch(Dep.target);
}
return val;
},
set(newVal) {
console.log('set', data, key);
val = newVal;
dep.notify();
}
});
vm._dep=dep
}
function observe(vm,data) {
if (data instanceof Object && data) {
Object.keys(data).forEach(item => {
defineReactive(vm,data, item, data[item]);
});
} else {
return false;
}
}
function selfVue(data, elName, exp) {
this.data = data;
observe(this,data);
let ele = document.querySelector(elName);
ele.innerHTML = data[exp];
new watcher(this,exp,(vm, exp,value,oldValue)=>{
ele.innerHTML = value
})
return this
}
let self=new selfVue(
{
name: 'hellow',
},
'#root',
'name'
);
self.data.name="你好"
</script>
</body>
</html>