<!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>Vue</title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<h1>{{msg}}</h1>
<h1 v-html="msg"></h1>
<button @click="setMsg">设置</button>
</div>
<script type="text/javascript">
class Vue {
constructor(opations) {
this.$el = document.querySelector(opations.el);
this.$opations = opations;
this.$watchEvent = {};
this.peoxyData(); //代理opations的data数据
this.obsevice(); //监听
this.compile(this.$el); //编译
}
peoxyData() {
for (let key in this.$opations.data) {
Object.defineProperty(this, key, {
configurable: false,
enumerable: true,
get() {
return this.$opations.data[key]
},
set(val) {
this.$opations.data[key] = val;
}
})
}
}
obsevice() {
for (let key in this.$opations.data) {
let value = this.$opations.data[key];
let self = this;
Object.defineProperty(this.$opations.data, key, {
configurable: false,
enumerable: true,
get() {
return value
},
set(val) {
value = val;
if (self.$watchEvent[key]) {
self.$watchEvent[key].forEach((item, index) => {
item.updata()
});
}
}
})
}
}
compile($el) {
$el.childNodes.forEach((node, index) => {
if (node.nodeType == 1) {
if (node.hasAttribute("v-html")) {
let vmKey = node.getAttribute("v-html").trim();
node.innerHTML = this[vmKey];
let watcher = new Watch(this, vmKey, node, "innerHTML");
this.$watchEvent[vmKey] = [...(this.$watchEvent[vmKey] || []), watcher];
node.removeAttribute("v-html");
}
if (node.hasAttribute("v-model")) {
let vmKey = node.getAttribute("v-model").trim();
if (this.hasOwnProperty(vmKey)) {
node.value = this[vmKey];
let watcher = new Watch(this, vmKey, node, "value");
this.$watchEvent[vmKey] = [...(this.$watchEvent[vmKey] || []), watcher];
node.addEventListener("input", e => {
this[vmKey] = node.value
})
node.removeAttribute("v-model");
}
}
if (node.hasAttribute("@click")) {
let vmKey = node.getAttribute("@click").trim();
node.addEventListener("click", e => {
this.$opations.methods[vmKey].call(this, e)
})
node.removeAttribute("@click");
}
}
if (node.nodeType == 3) {
let reg = /\{\{(.*?)\}\}/;
let text = node.textContent;
node.textContent = node.textContent.replace(reg, (val, vmKey) => {
vmKey = vmKey.trim();
if (this.hasOwnProperty(vmKey)) {
node.value = this[vmKey];
let watcher = new Watch(this, vmKey, node, "textContent");
this.$watchEvent[vmKey] = [...(this.$watchEvent[vmKey] || []), watcher];
}
return this[vmKey]
})
}
if (node.childNodes.length > 0) {
this.compile(node)
}
})
}
};
class Watch {
constructor(vm, key, node, attr, aType) {
this.vm = vm; //Vue实力对象
this.key = key; //绑定的属性
this.node = node; //html节点
this.attr = attr; //绑定的属性名称
}
updata() {
this.node[this.attr] = this.vm[this.key];
}
}
let app = new Vue({
el: "#app",
data: {
msg: "ASD"
},
methods: {
setMsg() {
this.msg = "QWE"
}
}
})
</script>
</body>
</html>
Vue简单实现
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。