59 lines
1.7 KiB
JavaScript
59 lines
1.7 KiB
JavaScript
import Dep from "./Dep.js";
|
|
import Watcher from "./Watcher.js";
|
|
export function observer(vm, obj) {
|
|
const dep = new Dep(); // 创建一个发布者实例
|
|
Object.keys(obj).forEach((key) => {
|
|
let internalValue = obj[key]; // 保存内部值
|
|
Object.defineProperty(vm, key, {
|
|
get() {
|
|
// 在获取响应式数据的时候,要做依赖的收集
|
|
if (Dep.target) {
|
|
dep.addSub(Dep.target);
|
|
}
|
|
return internalValue;
|
|
},
|
|
set(newVal) {
|
|
// 在设置响应式数据的时候,要做依赖的通知
|
|
internalValue = newVal;
|
|
dep.notify();
|
|
},
|
|
});
|
|
});
|
|
}
|
|
export function compile(vm) {
|
|
const el = document.querySelector(vm.$el);
|
|
if (!el) {
|
|
throw new Error(`Element with selector "${vm.$el}" not found.`);
|
|
}
|
|
const documentFragment = document.createDocumentFragment();
|
|
const reg = /\{\{(.*)\}\}/;
|
|
while (el.firstChild) {
|
|
const child = el.firstChild;
|
|
if (child.nodeType === Node.ELEMENT_NODE) {
|
|
const element = child;
|
|
if (reg.test(element.innerHTML || "")) {
|
|
const vmKey = RegExp.$1.trim();
|
|
new Watcher(vm, child, vmKey);
|
|
} else {
|
|
Array.from(element.attributes).forEach((attr) => {
|
|
if (attr.name === "v-model") {
|
|
const vmKey = attr.value;
|
|
element.addEventListener("input", (event) => {
|
|
const target = event.target;
|
|
vm[vmKey] = target.value;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
} else if (
|
|
child.nodeType === Node.TEXT_NODE &&
|
|
reg.test(child.nodeValue || "")
|
|
) {
|
|
const vmKey = RegExp.$1.trim();
|
|
new Watcher(vm, child, vmKey);
|
|
}
|
|
documentFragment.appendChild(child);
|
|
}
|
|
el.appendChild(documentFragment);
|
|
}
|