前言

虚拟Dom想必大家并不陌生,这是我学习虚拟Dom的一篇笔记,作为一个记录。

<div id="app">
      <div>test</div>
      <div>
        <span>123</span>
      </div>
</div>复制代码

这是我们常规的Dom结构,那么想要表示这个Dom结构,用虚拟Dom应该怎么表示呢?

VirtualElement

我们知道Dom节点打印出来是一个对象,所以我们可以用JavaScript中的对象来描述Dom节点。来一个“虚拟节点”的构造函数。

function VirtualElement(tagName, props, children) {
    this.tagName = tagName
    this.props = props || {}
    this.children = children || []
}复制代码

这里只考虑了最简单的情况,就是节点的标签、属性和它子节点。那么我们就可以这样来描述上述的Dom结构。

let vdom = new VirtualElement("div", { id: "app" }, [
        new VirtualElement("div", {}, ["test"]),
        new VirtualElement("div", {}, [new VirtualElement("span", {}, ["123"])
]);复制代码

在控制台中打印如下

Render

接下来就把他渲染成真正的Dom,我们在他的原型上定义一个方法。

VirtualElement.prototype.render = function () {}复制代码

接着拿到属性

const tagName = this.tagName;
const props = this.props || {};
const children = this.children || [];复制代码

然后用document.createElement()生成一个真实的Dom节点

let tag = document.createElement(tagName)复制代码

处理属性

let propKeys = Object.keys(props) if (propKeys.length > 0) {
        propKeys.forEach(item => {
            tag.setAttribute(item, props[item])
        })
    }复制代码

递归处理子节点

if (children.length > 0) {
        children.forEach(item => { let childTag if (item instanceof VirtualElement) {
                childTag = item.render()
            } else {
                childTag = document.createTextNode(item)
            }
            tag.appendChild(childTag)
        })
    } return tag复制代码

来试一下挂载

```
 <div id="container"></div>```
<script> let container = document.getElementById("container"); let vdom = new VirtualElement("div", { id: "app" }, [
        new VirtualElement("div", {}, ["test"]),
        new VirtualElement("div", {}, [new VirtualElement("span",{}, ["123"]) ]) ]); setTimeout(()=>{
    container.appendChild(vdom.render())
},2000)
</script>复制代码


diff算法我写不出来。。。留下没有技术的泪水。好了下班了溜了