思路:首先使用{tag,props,text,children}析构vnode,再判断tag是否为undefined,如果没有标签则直接使用createTextNode方法创建文本节点并返回,反之使用createElement方法创建tag标签元素,并遍历props对象,使用setAttribute方法为元素设置属性,再遍历子元素数组,依次递归创建子元素,并使用appendChild方法挂载在父元素上,最后返回当前元素即可。

<script>
   var vnode = {
      tag: 'ul',
      props: {
        class: 'list'
      },
      text: '',
      children: [
         {
            tag: "li",
            props: {
              class: "item"
            },
            text: '',
            children: [
                 {
                     tag: undefined,
                     props: {},
                     text: '牛客网',
                     children: []
                  }
             ]
          },
          {
              tag: "li",
              props: {},
              text: '',
              children: [
                   {
                       tag: undefined,
                       props: {},
                       text: 'nowcoder',
                       children: []
                   }
               ]
            }
         ]
     }
     const _createElm = vnode => {
        //析构vnode
        const {tag,props,text,children} = vnode
        //如果为空节点则直接创建文本节点并返回
        if(tag==undefined)
          return document.createTextNode(text)
        //否则创建tag元素
        const el=document.createElement(tag)
        //为节点添加属性
        for(let key in props)
          el.setAttribute(key,props[key])
        children.forEach(item=>{
          //将子元素挂载到父元素上
        el.appendChild(_createElm(item))
     })
     return el
   }
</script>

总结:createTextNode(文本)用于创建文本节点;createElement(标签)方法创建tag标签元素;setAttribute(键,值)方法为元素设置属性;父元素.appendChild(子元素)为父元素添加子元素。