55 lines
1.4 KiB
HTML
55 lines
1.4 KiB
HTML
<!DOCTYPE html>
|
|||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>手写虚拟dom</title>
|
||
|
|
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<script type="text/babel">
|
||
|
|
/*@jsx createElement*/
|
||
|
|
|
||
|
|
//虚拟dom
|
||
|
|
let vDom=(<div id="app" name="chenxuan">
|
||
|
|
<li name="world">hello world1!</li>
|
||
|
|
<li name="kitty">hello world2!</li>
|
||
|
|
<li name="world"><span>123</span></li>
|
||
|
|
</div>);
|
||
|
|
|
||
|
|
function createElement(nodeName,attr,...args){
|
||
|
|
console.log([].concat(...args))
|
||
|
|
return {nodeName:nodeName,attr:attr,children:[].concat(...args)}
|
||
|
|
}
|
||
|
|
|
||
|
|
function render(vnode){
|
||
|
|
|
||
|
|
//文本
|
||
|
|
if(vnode.split){
|
||
|
|
return document.createTextNode(vnode);
|
||
|
|
}
|
||
|
|
|
||
|
|
//非文本
|
||
|
|
else{
|
||
|
|
//创建根节点
|
||
|
|
let node=document.createElement(vnode.nodeName);
|
||
|
|
|
||
|
|
//递归节点
|
||
|
|
(vnode.children || []).forEach((n)=>{
|
||
|
|
node.appendChild(render(n))
|
||
|
|
})
|
||
|
|
return node;
|
||
|
|
|
||
|
|
//添加属性
|
||
|
|
let attr=vnode.attr || {};
|
||
|
|
Object.keys(attr).forEach((k)=>{
|
||
|
|
node.setAttribute(k,attr[k])
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
let dom=render(vDom);
|
||
|
|
document.body.appendChild(dom);
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|