Skip to content

Instantly share code, notes, and snippets.

@Teemwu
Last active September 15, 2021 01:51
Show Gist options
  • Save Teemwu/f0efc99986c68270e8a54ba8acfea2c3 to your computer and use it in GitHub Desktop.
Save Teemwu/f0efc99986c68270e8a54ba8acfea2c3 to your computer and use it in GitHub Desktop.
虚拟 DOM 转真实 DOM
'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