iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
Modern Web

Web Component 網頁元件之路系列 第 28

[Day28] - Vue 的 Html 字串處理 ( renderer 介紹 )

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>

上一篇
[day27] - Vue 的 Html 字串處理 ( 簡易版 parser 實作 )
下一篇
[day29] - the diff function in Vue
系列文
Web Component 網頁元件之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言