<!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>
//先判斷作用域內(nèi)部是否有子元素
function isChild(node){
if(node.childNodes.length===0){
return false
}
else{
return node
}
}
//將節(jié)點(diǎn)加入文檔碎片
function nodeToFragment(node,vm){
var frag= document.createDocumentFragment();
var child;
while(child = node.firstChild){
//開始賦值
compile(child,vm);
if(isChild(child)){
//判斷子節(jié)點(diǎn)內(nèi)部的子節(jié)點(diǎn)
nodeToFragment(isChild(child),vm)
}
frag.appendChild(child)
}
node.appendChild(frag);
//將碎片在加入作用域
}
function compile(node,vm){
if(node.nodeType === 1){
//如果節(jié)點(diǎn)為元素
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){
//如果為文本 進(jìn)行正則判斷
var reg = /\{\{(.*)\}\}/;
if(reg.test(node.nodeValue.trim())){
//將正則匹配到的{{}}中的字符串賦值給name
var name = RegExp.$1;
//利用name對應(yīng)賦值相應(yīng)的節(jié)點(diǎn)值
node.nodeValue = vm.data[name];
}
}
}
function Vue(options){
//封裝一個(gè)vue
this.id=options.el;
this.data=options.data;
nodeToFragment(document.getElementById(this.id),this)
}
var vm=new Vue({
//初始化一個(gè)vue
el:'app',
data:{
msg:'hello,two-ways-binding'
}
})
</script>
</body>
</html>