function h(tag, children) {
return { tag, children }
}
/**
* transform the ast to vnode
*
* { type: 'tag', tag:'div', children: [...] } => h("ul", [...])
* @param ast {object} - { type: 'tag', tag:'div', children: [...] }
* @returns {object} vnode = h("ul", [...])
*/
const transformer = ast => {
const getChildren = children => {
if (!children) return undefined;
else if (children.length === 0) return undefined;
else if (children.length === 1) return transformer(children[0]);
else return children.map(transformer);
}
if (ast.type === 'Root')
return h('Root', getChildren(ast.children))
else if (ast.type === 'tag')
return h(ast.tag, getChildren(ast.children))
else if (ast.type === 'text')
return ast.content
else throw new Error('[@@@@@@] unknown ast type !!')
}
const ast01 = {
"type": "Root",
"children": [
{
"type": "tag",
"tag": "div",
"children": [
{
"type": "text",
"content": "Hello World"
}
]
}
]
}
const vnode01 = transformer(ast01)
console.log(vnode01.toString());
/*
h("Root", [ h("div", "Hello World") ]);
*/
<body>
<div id="app"></div>
<script>
const h = (tagName, children) => {
const element = document.createElement(tagName)
if (typeof children === 'string')
element.innerText = children
else if (Array.isArray(children))
children.forEach(child => element.appendChild(child))
else if (typeof children === HTMLElement)
element.appendChild(children)
return element
}
const mountIt = (selector, element) => {
document.querySelector(selector).appendChild(element)
}
const App = h("ul", [
h("li", "Item_1"),
h("li", "Item_2")
]);
mountIt('#app', App);
</script>
</body>