首先将该任务分为几个子任务:
- 输入框以及文本节点与data中的数据绑定
- 输入框内容变化时,data中的数据同步变化。即view=>model的变化
- data中的数据变化时,文本节点的内容同步变化。即model=>view的变化。
任务一:数据初始化绑定
了解文档片段(DocumentFragment)
DocumentFragment(文档片段)可以看作节点容器,它可以包含多个子节点,当我们将它插入到DOM中时,只有它的子节点会插入目标节点,所以把它看作一组节点的容器。使用DocumentFragment处理节点,速度和性能远远优于直接操作DOM。vue编译时,就是将挂载目标的所有子节点劫持(真的是劫持,通过append方法.DOM中的节点会被自动删除)到DocumentFragment中,经过一番处理后,再将DocumentFragment整体返回插入挂载目标.
<div id="app">
<input type="text" v-model="text">
{{text}}
</div>
<script>
var vm=new Vue({
el:"app",
data:{
text:"hello world"
}
});
//创建vue对象
function Vue(options){
this.data=options.data;
var id=options.el;
var dom=nodeToFragment(document.getElementById(id),this);
document.getElementById(id).appendChild(dom);
}
//编译模板
function complie(node,vm){
var reg=/\{\{(.*)\}\}/;
//节点类型为元素
if(node.nodeType===1){
var attr=node.attributes;
//解析属性
for(var i=0;i<attr.length;i++){
if(attr[i].nodeName==='v-model'){
var name=attr[i].nodeValue;
node.value=vm.data[name];
node.removeAttribute('v-model');
}
}
}
//节点类型为text
if(node.nodeType===3){
if(reg.test(node.nodeValue)){
var name=RegExp.$1;
name=name.trim();
node.nodeValue=vm.data[name];
}
}
}
//创建文档片段
function nodeToFragment(node,vm){
var flag=document.createDocumentFragment();
var child;
while(child=node.firstChild){
complie(child,vm);
flag.appendChild(child)
}
return flag;
}
</script>