html代码:
Document
{{ clickHere }}
{{ str }}
{{ clickHere }}
let myVue = new Vue({
el: "#app",
data: {
str: "你好234",
clickHere: "点击这里",
},
methods: {
func1(e) {
this.clickHere = "点击这里aaa"
console.log(this.clickHere);
console.log(this);
console.log(e);
}
}
})
--------------------------------------------------------
js代码:
class Vue {
constructor(options) {
this.options = options;
this.$el = document.querySelector(options.el);
this.$data = options.data;
this.$methods = options.methods;
this.$watchEvent = {};
this.proxyData();
this.compile(this.$el);
}
proxyData() {
let that = this;
for (let key in that.$data) {
// 劫持 Vue(this) 的属性
Object.defineProperty(
that,
key,
{
get: function () {
console.log("获取 data." + key + "的值: ", that.$data[key])
return that.$data[key];
},
set: function (val) {
that.$data[key] = val;
if (that.$watchEvent[key]) {
that.$watchEvent[key].forEach((item, index) => {
item.update()
})
}
}
}
)
}
}
compile(node) {
let that = this;
node.childNodes.forEach((item, index) => {
// nodeType == 1 => node 节点, 带标签
if (item.nodeType == 1) {
// 递归节点-----------------------------------------------------------
if (item.childNodes.length > 0) {
// 数据绑定
this.compile(item);
}
// @click 方法绑定-----------------------------------------------------------
if (item.hasAttribute("@click")) {
// 获取方法名
let funName = item.getAttribute("@click").trim();
item.addEventListener('click', function (event) {
// 执行该方法名对应的方法 .call() 改变this指向为Vue 对象
that.$methods[funName].call(that, event);
console.log("compile : ", that);
})
}
// v-model 绑定-----------------------------------------------------------
if (item.hasAttribute("v-model")) {
// 获取方法名
let funName = item.getAttribute("v-model").trim();
// 将数据绑定到视图
item.value = that[funName];
item.addEventListener('input', function (event) {
// 监听视图数据绑定到 model
that[funName] = item.value;
})
}
//-----------------------------------------------------------
}
// nodeType == 3 => 文本节点 不包含标签
if (item.nodeType == 3) {
let reg = /\{\{(.*?)\}\}/g;
let text = item.textContent;
item.textContent = text.replace(reg, function (match, vmKey) {
/*
function 参数 : 第一个是 匹配的全部字符
第二个是 第一个元组
第三个是 第二个元组
...
*/
vmKey = vmKey.trim();
if (that[vmKey]) {
console.log(that[vmKey]);
let watcher = new Watch(that, vmKey, item, "textContent")
if (that.$watchEvent[vmKey]) {
that.$watchEvent[vmKey].push(watcher)
} else {
that.$watchEvent[vmKey] = [];
that.$watchEvent[vmKey].push(watcher)
}
}
return that.$data[vmKey];
})
}
});
}
}
// 用来动态更新视图
class Watch {
constructor(vm, key, node, attr) {
this.vm = vm;
this.key = key;
this.node = node;
this.attr = attr;
}
update() {
this.node[this.attr] = this.vm[this.key];
}
}