源码 感兴趣的小伙伴可以去看视频,讲的很清楚了
class Vue {
constructor(options) {
this.$data = options.data;
Observe(this.$data);
Object.keys(this.$data).forEach((key) => {
Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
get() {
return this.$data[key];
},
set(newValue) {
this.$data[key] = newValue;
},
});
});
Compile(options.el, this);
}
}
function Observe(obj) {
if (!obj || typeof obj !== "object") {
return;
}
const dep =new Dep()
Object.keys(obj).forEach((key) => {
let value = obj[key];
Observe(value);
Object.defineProperty(obj, key, {
get() {
Dep.target && dep.addSub(Dep.target)
return value;
},
set(newValue) {
value = newValue;
Observe(value);
dep.notify();
},
});
});
}
function Compile(element, vm) {
vm.$el = document.querySelector(element);
let fragment = document.createDocumentFragment();
while ((childNode = vm.$el.firstChild)) {
fragment.appendChild(childNode);
}
replace(fragment, vm);
vm.$el.appendChild(fragment);
}
function replace(node, vm) {
const regMustache = /\{\{\s*(\S+)\s*\}\}/;
if (node.nodeType === 3) {
const text = node.textContent;
const execResult = regMustache.exec(text);
if (execResult) {
const value = execResult[1].split(".").reduce((newObj, k) => {
return newObj[k];
}, vm);
node.textContent = text.replace(regMustache, value);
console.log(execResult[1])
new Watcher(vm,execResult[1],(newValue)=>{
node.textContent = text.replace(regMustache, newValue);
})
}
return;
}
node.childNodes.forEach((node) => replace(node, vm));
}
class Dep {
constructor() {
this.subs = [];
}
addSub(watcher) {
this.subs.push(watcher);
}
notify() {
this.subs.forEach((watcher) => watcher.update());
}
}
class Watcher {
constructor(vm, key, cd) {
this.vm = vm;
this.key = key;
this.cd = cd;
Dep.target =this
key.split('.').reduce((newObj,k)=>newObj[k],vm)
Dep.target=null
}
update() {
const value = this.key.split('.').reduce((newObj,k)=>newObj[k],vm)
this.cd(value)
}
}