示例
比如说,在body中的数据模板是这样的:
<body>
<div id="root">
<div>{{message}}</div>
</div>
</body>
而message的值在数据中是这样表示的:
var data = {
message: 'hello world'
};
那么在界面中如何让它显示hello world呢?
实现原理讲解
核心原理非常简单,就是使用正则判断文本节点的 {{ }} 的问题。
第一步:
//第一步,获取入口节点,并且创建一个文档碎片。
var $el = document.querySelector('#root');
//console.log($el);
var fragment = document.createDocumentFragment();
fragment.appendChild($el);
//console.log(fragment);
第二步:
function isTextNode(node) {
return node.nodeType == 3;
}
function compileElement(fragment) {
var childNodes = fragment.childNodes;
[].slice.call(childNodes).forEach(function (node) {
var text = node.textContent;
var reg = /\{\{(.*)\}\}/;
if(node.childNodes && node.childNodes.length){
compileElement(node)
} else if(isTextNode(node) && reg.test(text)) {
//console.log('底层文本解析',RegExp.$1);
let thisText = data[RegExp.$1];
node.textContent = thisText;
}
});
//console.log('最终的fragment',fragment)
return fragment;
}
var mycompile = compileElement(fragment);
第三步:
document.body.appendChild(mycompile);
完整的代码演示示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue指令解析过程</title>
</head>
<body>
<div id="root">
<div>{{message}}</div>
</div>
</body>
<script>
var data = {
message: 'hello world'
};
//第一步,获取入口节点,并且创建一个文档碎片。
var $el = document.querySelector('#root');
//console.log($el);
var fragment = document.createDocumentFragment();
fragment.appendChild($el);
//console.log(fragment);
//第二步,遍历解析
function compileElement(fragment) {
var childNodes = fragment.childNodes;
[].slice.call(childNodes).forEach(function (node) {
var text = node.textContent;
var reg = /\{\{(.*)\}\}/;
if(node.childNodes && node.childNodes.length){
compileElement(node)
} else if(isTextNode(node) && reg.test(text)) {
console.log('底层文本解析',RegExp.$1);
let thisText = data[RegExp.$1];
node.textContent = thisText;
}
});
//console.log('最终的fragment',fragment)
return fragment;
}
var mycompile = compileElement(fragment);
console.log(mycompile);
document.body.appendChild(mycompile);
function isTextNode(node) {
return node.nodeType == 3;
}
</script>
</html>