I did some research on virtual DOM rendering, and then I tried to implement it with ES6.

Github:github.com/Huoshendame…

Title: Given a tree structure of JSON, implement VDOM

let demoNode = {
    tagName: 'ul',
    props: {'class':'list'},
    children: [
        {
            tagName: 'li',
            props: {'class':'item'},
            children: ['Three Kindom']
        },
        {
            tagName: 'li',
            props: {'class':'item'},
            children: ['START GAME']]}}Copy the code

Ideas:

1. Define a parent class that instantiates DOM generating elements in the tree structure as subclasses.

2. Define the render function of the parent class to render the VDOM into the real DOM.


— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — beautiful line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — –


Let’s implement it step by step in code.

First define an Element class and then its constructor

class Element {

    constructor(props){
  
    }


}Copy the code

Next we define its initialization method, which is instantiated as a subclass.

(One might ask here why instantiate as a subclass?)

Since subclasses also use the render function to render themselves, subclasses -> subclasses -> last subclasses – are instantiated as Subclasses of Element using binary tree depth-first traversal. A method that inherits from a parent class through __proto__. The Render method.)

class Element {

    constructor(props){
      this.init(props)
    }

    init(props){
        this.tagName = props.tagName || ' '
        this.props = props.props || {}
        this.children = props.children || []
        let _child = []
        this.children = this.children.map((child) => {
            if(typeof child == "object" ){
                child = new Element(child)
            }
            return child
        })
    }
}Copy the code

Let’s define his render method.

1. Create the current node

2. Assign the attribute to the current node

3. Traverse his child nodes.

(1) If it is a subclass of Element, then it is a VDOM that can generate the DOM. We then recurse to the Render method to create and initialize it.

(2) If it is not a subclass of Element, prove to be the value of the last node. Just assign it.

class Element(a){

    constructor(props){... } init(props){... } render(){let ele = document.createElement(this.tagName)        
        for (let propsName in this.props){            
            ele.setAttribute(propsName, this.props[propsName])        
        }        
        this.children.forEach(function(item ,index){            
            let childELement = null 
            if( item instanceof Element){
                childELement = item.render()
            }else{
                childELement = document.createTextNode(item)
            }
            ele.appendChild(childELement)
        })
        return ele
    }}Copy the code

By defining the above classes, we are done rendering the virtual DOM. You can run it and try it out.

let demoElement = newElement (demoNode);document. The body. The appendChild (demoElement. Render ());Copy the code