index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
>
<title>Document</title>
</head>
<body>
<div id="app">{{msg}}
<h3>{{str}}</h3>
<button @click="changeMsg">changeMsg</button>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: 'hello world',
str: 'hello',
},
methods: {
changeMsg(e) {
//this.msg = 'hello vue'
console.log('fadsfadf')
console.log(e)
console.log(this.msg)
}
},
// beforeCreate() {
// console.log('beforeCreate', this.$data)
// },
// created() {
// // 这里需要改变 this 的指向,否则获取不到 $data
// console.log('created', this.$data)
// },
// beforeMount() {
// console.log('beforeMount', this.$el)
// },
// mounted() {
// console.log('mounted', this)
// }
})
</script>
</body>
</html>
vue.js
class Vue {
constructor(options) {
this.$options = options;
if (typeof options.beforeCreate === "function") {
options.beforeCreate.bind(this)();
}
// 数据绑定
this.$data = options.data
this.proxyData(options.data);
if (typeof options.created === "function") {
options.created.bind(this)();
}
if (typeof options.beforeMount === "function") {
options.beforeMount.bind(this)();
}
// 节点
this.$el = document.querySelector(options.el);
// 解析节点
this.compile(this.$el);
if (typeof options.mounted === "function") {
options.mounted.bind(this)();
}
}
proxyData(data) {
Object.keys(data).forEach((key) => {
// 将 data 中的所有数据直接放入到 this(Vue实例) 上
Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
get() {
return data[key];
},
set(newValue) {
data[key] = newValue;
},
});
});
}
compile(node) {
if (node.childNodes && node.childNodes.length) {
node.childNodes.forEach((child) => {
// nodeType 1: 元素节点 3: 文本节点
if (child.nodeType === 3) {
// 文本节点
let reg = /\{\{(.*)\}\}/;
let text = child.textContent;
// 给节点赋值
child.textContent = text.replace(reg, (matched, value) => {
value = value.trim();
return this.$data[value];
});
}
// 元素节点
if (child.nodeType === 1) {
if (child.hasAttribute("@click")) {
child.addEventListener("click", (e) => {
this.eventFn = this.$options.methods[child.getAttribute("@click").trim()].bind(this);
this.eventFn(e);
});
}
if (child.childNodes && child.childNodes.length) {
this.compile(child);
}
}
});
}
}
}

6316

被折叠的 条评论
为什么被折叠?



