Last active
September 15, 2021 01:51
-
-
Save Teemwu/f0efc99986c68270e8a54ba8acfea2c3 to your computer and use it in GitHub Desktop.
虚拟 DOM 转真实 DOM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const astObj = { | |
tag: 'DIV', | |
attrs: { | |
id: 'app' | |
}, | |
children: [ | |
{ | |
tag: 'SPAN', | |
children: [ | |
{ tag: 'A', children: [] } | |
] | |
}, | |
{ | |
tag: 'SPAN', | |
children: [ | |
{ tag: 'A', children: [] }, | |
{ | |
tag: 'A', children: [ | |
{ | |
tag: 'I', | |
attrs: { | |
class: 'icon' | |
} | |
} | |
] | |
} | |
] | |
} | |
] | |
}; | |
/** | |
* 虚拟 DOM 转真实 | |
* @param {object} ast HTML 抽象树对象 | |
* @returns DOM 树 | |
*/ | |
function render(ast) { | |
const _render = ({ tag, attrs, children }, tree = '', index = 0) => { | |
// 空格计算 | |
const space = new Array(index * 4).fill(' ').join(''); | |
// 是否存在子级 | |
const hasChildren = children && children.length | |
// 标签转小写 | |
tag = tag.toLowerCase(); | |
// 标签开头部分组装 | |
tree += `${space}<${tag}`; | |
// 属性遍历组装 | |
for (let key in attrs) { | |
tree += ` ${key}="${attrs[key]}"`; | |
} | |
// 标签开头结束和换行 | |
tree += `>${hasChildren ? '\n' : ''}`; | |
// 遍历获取子级结构 | |
if (hasChildren) { | |
children.forEach(i => { | |
tree += _render(i, '', index + 1); | |
}) | |
} | |
// 标签结尾 | |
tree += `${hasChildren ? space : ''}</${tag}>\n`; | |
return tree; | |
} | |
return _render(ast) | |
} | |
console.log(render(astObj)); | |
// 输出如下: | |
// <div id="app"> | |
// <span> | |
// <a></a> | |
// </span> | |
// <span> | |
// <a></a> | |
// <a> | |
// <i class="icon"></i> | |
// </a> | |
// </span> | |
// </div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment