这段代码实现了一个递归渲染函数 Render
,用于将一个简单的虚拟 DOM 树结构渲染成真实的 DOM 节点并挂载到指定的根元素 root
上。以下是函数中每一部分的解释:
-
创建元素:
iniconst el = document.createElement(obj.tag);
根据
obj.tag
创建一个对应的 HTML 元素。例如,如果obj.tag
是'div'
,这行代码会创建一个<div>
元素。 -
处理
children
为文本的情况:iniif (typeof obj.children === 'string') { const text = document.createTextNode(obj.children); el.appendChild(text); }
如果
obj.children
是字符串类型,则它是一个文本节点。使用document.createTextNode
创建一个文本节点,并将其作为子节点添加到当前的元素el
中。 -
处理
children
为数组的情况(递归渲染子节点):scsselse if (obj.children) { obj.children.forEach((child) => Render(child, el)); }
如果
obj.children
是一个数组,则递归调用Render
函数,对每一个子对象进行渲染。将当前元素el
作为根元素传递,子节点会被添加到当前元素中。 -
将元素添加到根节点:
iniroot.appendChild(el);
最后,将创建好的元素
el
添加到传入的根节点root
中。
函数运行流程举例
对于下面的虚拟 DOM 结构:
css
const obj = {
tag: 'div',
children: [
{ tag: 'span', children: 'hello world' }
]
};
Render
被调用,创建一个<div>
元素。- 发现
obj.children
是一个数组,递归调用Render
,处理子节点{ tag: 'span', children: 'hello world' }
。 - 子节点的
tag
是'span'
,创建一个<span>
元素。 - 子节点的
children
是字符串'hello world'
,创建一个文本节点并添加到<span>
中。 - 将
<span>
添加到父节点<div>
中。 - 最后将整个
<div>
挂载到传入的根节点root
中。
渲染结果
在页面中生成的 HTML 结构为:
css
<div>
<span>hello world</span>
</div>