<!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>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model='name' class='qqq'>
<input type="text" v-model='age'>
<h1>{{name}}</h1>
<h2>{{age}}</h2>
</div>
</body>
</html>
<script>
function observe(data){
if(({}).toString.call(data) !== '[object Object]')return ;
let keys = Object.keys(data);
keys.forEach(key=>{
defineReactive$$1(data,key,data[key])
})
}
function defineReactive$$1(target,key,val){
var dep = new Dep();
Object.defineProperty(target,key,{
enumerable:true,
get(){
if(Dep.target){
dep.addSub(Dep.target)
}
return val
},
set(newV){
if(newV !== val){
val = newV
dep.notify()
}
}
})
}
function nodeToFragment(el,vm){
let fragment = document.createDocumentFragment();
let child;
while(child = el.firstChild){
compile(child,vm)
fragment.appendChild(child)
}
el.appendChild(fragment)
}
function compile(node,vm){
if(node.nodeType == 1){
let attrs = node.attributes;
[...attrs].forEach(item=>{
console.dir(item)
if(/^v-/.test(item.nodeName)){
let vName = item.nodeValue ;
let val = vm.$data[vName] ;
new Watcher(node,vName,vm)
node.value = val;
node.addEventListener('input',(e)=>{
vm.$data[vName] = e.target.value
})
}
});
[...node.childNodes].forEach(item=>{
compile(item,vm)
})
}else{
let str = node.textContent;
if(/\{\{(\w+)\}\}/.test(str)){
console.log(str)
str = str.replace(/\{\{(\w+)\}\}/,(a,b)=>{
new Watcher(node,b,vm)
return vm.$data[b]
})
console.log(str)
node.textContent = str;
}
}
}
class Dep{
constructor(){
this.subs = [];
}
addSub(sub){
this.subs.push(sub)
}
notify(){
this.subs.forEach(sub=>{
sub.update()
})
}
}
class Watcher{
constructor(node,key,vm){
Dep.target = this;
this.node = node;
this.key = key;
this.vm = vm;
this.getValue();
Dep.target = null
}
update(){
this.getValue();
if(this.node.nodeType == 1){
this.node.value = this.value
}else{
this.node.textContent = this.value
}
}
getValue(){
this.value = this.vm.$data[this.key];
}
}
function Vue(option){
this.$el = document.querySelector(option.el)
this.$data = option.data
observe(this.$data)
nodeToFragment(this.$el,this)
}
</script>
<script>
let vm = new Vue({
el:'#app',
data:{
name:"珠峰",
age:11
}
});
</script>