vue原理系列
编译模板Compile
匹配花括号里的内容并替换
<div id="app">
<p>{{ a.a }}</p>
<p>{{ b }}</p>
</div>
el=document.querySelector('#app');
let fragment = document.createDocumentFragment();
while(child=el.firstChild){
fragment.append(child)
}
el.appendChild(fragment)
------------------------------------------------------------------------还是挺好玩的
js拿到el绑定的元素
vm.$el=document.querySelector(el);
转移到内存中
let fragment = document.createDocumentFragment()
这边一个小技巧就是一直取el中的第一个并插入到fragment就可以一直循环了
while(child=vm.$el.firstChild){
fragment.append(child)
}
遍历文档片段 fragment 用Array.from把类数组转成数组然后遍历每一层,拿到每个节点, 判断节点是否是文本节点(nodeType===3)
,从节点里取出文本,而且正则匹配是正确的就是要替换的内容,然后对取出的内容进行拆解成数组,拆的数组再进行遍历,然后一个小技巧每次遍历都取出来赋值回去那个局部变量,然后把变量传回去
如果没有取到需要递归往下取 (我觉得其实可以用for of也是可以遍历,但有兼容性问题)
replace(frag)
function replace(frag){
Array.from(fragment.childNodes).forEach(function(node){
let text = node.textContent;
let reg = /\{\{(.*)\}\}/;
if(node.nodeType === 3 && reg.test(text)){
console.log(RegExp.$1) //a.a.a a.b
let arr = (RegExp.$1.split('.') //[a,a]
let val = vm;
arr.forEach(function(key){
val = val[k]; //第一次val[k] 第二次val[k][k] ...
})
node.textContent = text.replace(reg.val)
}
if(node.childNodes){
replace(node)
}
})
}
然后在放进$el
vm.$el.appendChild(fragment)