<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
{{msg}}
</div>
<script>
//先判断作用域内部是否有子元素
function isChild(node){
if(node.childNodes.length===0){
return false
}
else{
return node
}
}
//将节点加入文档碎片
function nodeToFragment(node,vm){
var frag= document.createDocumentFragment();
var child;
while(child = node.firstChild){
//开始赋值
compile(child,vm);
if(isChild(child)){
//判断子节点内部的子节点
nodeToFragment(isChild(child),vm)
}
frag.appendChild(child)
}
node.appendChild(frag);
//将碎片在加入作用域
}
function compile(node,vm){
if(node.nodeType === 1){
//如果节点为元素
var attr = node.attributes;
//获取该元素的属性
for(var i=0;i<attr.length;i++){
//获取自定义属性 v-model
if(attr[i].nodeName === 'v-model'){
//获取值 则为 data.属性名 v-model="msg"中的msg
var name = attr[i].nodeValue;
//该元素的 值为app 中data 的
node.value=vm.data[name];
//使用后删除该属性
node.removeAttribute(attr[i].nodeName)
}
}
}
if(node.nodeType === 3){
//如果为文本 进行正则判断
var reg = /\{\{(.*)\}\}/;
if(reg.test(node.nodeValue.trim())){
//将正则匹配到的{{}}中的字符串赋值给name
var name = RegExp.$1;
//利用name对应赋值相应的节点值
node.nodeValue = vm.data[name];
}
}
}
function Vue(options){
//封装一个vue
this.id=options.el;
this.data=options.data;
nodeToFragment(document.getElementById(this.id),this)
}
var vm=new Vue({
//初始化一个vue
el:'app',
data:{
msg:'hello,two-ways-binding'
}
})
</script>
</body>
</html>