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