模板字符串转换成===>>>虚拟DOM(vnode)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root" data-attr="hahah">
一级
<div>
二级
<div>三级</div>
</div>
</div>
<script>
// 用于生成vnode的对象的类 --VNode类
class VNode {
constructor(tag, data, value, type) {
this.tag = tag ? tag.toLowerCase() : tag;
this.data = data;
this.value = value;
this.type = type;
this.children = [];
}
appendChild(node) {
this.children.push(node);
}
}
// 解析器函数 --简化版
function compiler(node) {
let nodeType = node.nodeType;
let _vnode = null;
if (nodeType === 1) {
let attrs = node.attributes;
let obj = {};
for (let i = 0; i < attrs.length; i++) {
obj[attrs[i].nodeName] = attrs[i].nodeValue;
}
_vnode = new VNode(node.nodeName, obj, undefined, nodeType);
let childNodes = node.childNodes;
for (let i = 0; i < childNodes.length; i++) {
_vnode.appendChild(compiler(childNodes[i]));
}
} else if (nodeType === 3) {
_vnode = new VNode(undefined, undefined, node.nodeValue, nodeType);
}
return _vnode;
}
console.log(compiler(document.getElementById("root")));
</script>
</body>
</html>
执行效果如下:
编写一个根据路径获取对象路径的方法:
let obj = {
a: {
b: {
c: {
d: 1,
},
},
},
};
function getPropsByPath(obj, path) {
let keys = path.split(".");
let targetObj = obj;
let prop;
while ((prop = keys.shift())) {
if (!targetObj[prop]) {
alert(`属性:${prop} 不存在`);
break;
}
targetObj = targetObj[prop];
}
return targetObj;
}
console.log(getPropsByPath(obj, "a.b.c.d"));
// 把虚拟dom转换成真实dom
function parseVNode(vnode) {
let type = vnode.type;
let data = vnode.data;
let realDom = null;
if (type === 1) {
realDom = document.createElement(vnode.tag);
if (data) {
for (let k in data) {
realDom.setAttribute(k, data[k]);
}
}
if (vnode.children && 0 in vnode.children) {
for (let i = 0; i < vnode.children.length; i++) {
realDom.appendChild(parseVNode(vnode.children[i]));
}
}
} else if (type === 3) {
return document.createTextNode(vnode.value);
}
return realDom;
}
console.log(parseVNode(compiler(document.getElementById(“root”))));