手摸手实现简易render函数

203 阅读1分钟

废话不多说,直接上代码~~

设置dom属性值

const setVDom = (node, key, value) => {
  switch(key) {
    // 增加样式
    case 'style':
      if (typeof value === 'string') {
        node.style.cssText = value;
      }
      if (typeof value === 'object') {
        for(let key in value) {
          node.style[key] = value[key];
        }
      }
      break;
    // 赋值
    case 'value':
      let tagName = node.tagName || '';
      tagName = tagName.toLowerCase();
      if (['input', 'textarea'].includes(tagName)) {
        node.value = value;
      } else {
        node.setAttribute(key, value);
      }
      break;
    // 新增事件
    case 'on':
      for(let key in value) {
        node['on'+key.toLowerCase()] = value[key];
      }
      console.log(node, key, value);
      break;
    // 增加其他属性
    default:
      node.setAttribute(key,value);
      break;
  }
 }

创建 Element 类

 class Element{
  constructor(tagName, attrs = {}, child = []){
    this.tagName = tagName;
    this.attrs = attrs;
    this.child = child;
  }
  render(){
    let ele = document.createElement(this.tagName)
    let attrs = this.attrs;
    for(let key in attrs) {
      setVDom(ele,key,attrs[key])
    }
    let childNodes = this.child;
    childNodes.forEach((child) => {
      let childEle = child instanceof Element ? child.render() : document.createTextNode(child);
      ele.appendChild(childEle);
    })
    return ele;
  }
}

实例化Element

const h = (tag,attr,child) => {
  return new Element(tag,attr,child)
}

h函数的使用

 const ulElement = h('ul', {id: 'list'}, [
  h('li', {
    style: {color: 'red',fontSize:'12px'}, /** 设置style样式 */
    class: 'red',  /** 设置类名 */
    on: { /** 绑定事件 */
      click(e) {
        console.log(e);
      }
    }
  },['绑定事件']),
  h('li', {style: 'color: #ccc'},['创建元素li']),
  h('li', {style: 'color: blue'}, [
    '创建元素li',
    h('input', {
      style: 'color: green',
      value: '创建元素input',
      on: {
        keyup(e) {
          console.log(e.target.value)
        }
      }
    }),
    h('p', {style: 'color: green',value: 'green'},['创建元素p']),
  ])
]);

插入dom树到页面

    <template>
      <div ref="realDom"></div>
    </template>
    
    this.$refs.realDom.appendChild(this.RealDom)