Initialize the project

Add the following tags under public/index.html

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />  // Ie compatible mode
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no" /> // Ios default event
<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = no" /> // Mobile adapter
Copy the code

Remove common styles

Create the Pages directory and asset directory and delete unnecessary files

In app.js, the stateless component of function is a stateful component

Experience JSX for the first time, variables wrapped in curly braces

Render () {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render() {render(); Return (<div className="App"> {username} <div dangerouslySetInnerHTML={{__html:content}}></div> </div> ) } } export default App;Copy the code

3. Obtain the virtual DOM through ref

Class App extends react.componentDidmount () {console.log(this.refs.node.innerhtml)} render() <span style='color: RGB (0, 0, 0); Return (<div className="App"> {username} <div dangerouslySetInnerHTML={{__html:content}}></div> <div ref="node"> </div> </div>)}} export default App;Copy the code

4. Obtain the virtual DOM through reactDom

Ref can only get the DOM in this component, and use the reactDom to get it

import HeaderComponent from './component/header' import ReactDom from 'react-dom' class App extends React.Component { componentDidMount() { // console.log(this.refs.node.innerHTML) console.log(document.getElementById('header')) // Console. log(reactdom.finddomNode (document.getelementbyid ('header'))} render() {let username = 'username' let content = "<span style='color: Return (<div className="App"> {/* HeaderComponent */} <HeaderComponent /> {username} <div DangerouslySetInnerHTML = {{__html: content}} > < / div > {/ * < div ref = "node" > < / div > * / node information}}} < / div >)Copy the code

The principle of virtual Dom and Diff algorithm

1. Principle of virtual Dom

The virtual DOM is equivalent to adding a cache between JS and the real DOM, converting the real DOM into JSON objects, and using dom diff algorithm to avoid unnecessary DOM operations, thus improving performance.Copy the code

2. Principle of Diff algorithm

A diff function takes two parameters, a real Dom and a virtual Dom, using a recursive comparison of components, text nodes, non-text Dom nodes, and attributes. It does not update if they are identical, and only updates if they are different. Compare child nodes: The child nodes are different from the previous ones. They are an array, and they can change order or number. It is difficult to determine which node to compare to the virtual DOM. So we're going to give it a key, and if it has a key it looks up the value of the child node (high performance), if it doesn't have a key it looks up the DOM type (low performance)Copy the code

Six, handwritten JSX virtual DOM

1. Introduce the Babel

https://unpkg.com/babel-standalone@6/babel.min.js
Copy the code

2. Override the createElement method

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script SRC ="js/babel.min.js"></script> <script type="text/ Babel "> /*@jsx createElement*/ /@jsx Babel lets vmDom = (<div) id="app" name="app">hello</div>) function createElement(nodeName, attr, ... args) { console.log( {nodeName,attr,children: [].concat(... args)}) return {nodeName,attr,children: [].concat(... args)} } </script> </body> </html>Copy the code

Your JSX syntax was successfully created

Implement the render method

/*@jsx createElement*/ /@jsx Babel let vmDom = (<div id="app" name="app"> hello <ul> <li>1</li> </li> 2</li> </ul> </div>) /** * * @param nodeName * @param attr * @param args * @returns {{nodeName: "div", children: ["hello"], attr:{id: "app", name: "app"}}} */ function createElement(nodeName, attr... args) { return {nodeName,attr,children: [].concat(... args)} } function render(vnode) { console.log(vnode) } let dom = render(vmDom)Copy the code

Results the following

4. Recursively render the constructed virtual DOM tree into the real DOM

<script SRC ="js/babel.min.js"></script> <script type="text/ Babel "> let userList = [' zhang SAN ',' Bi si ',' Bi si '] /*@jsx CreateElement */ /@jsx Babel let vmDom = (<div id="app" name="app"> hello <ul> {userlist. map((v, I) => {return ()) <li key={i}>{v}</li> ) })} </ul> </div>) /** * * @param nodeName * @param attr * @param args * @returns {{nodeName: "div", children: ["hello"], attr:{id: "app", name: */ function createElement(nodeName, attr,... args) { return {nodeName:nodeName,attr:attr,children:[].concat(... Args)}} function render(vnode) {console.log(vnode) // if(vnode.split) {return document.createTextNode(vnode)} / / if the node is let the node = document. The createElement method (vnode. NodeName) / / node properties let attr = vnode. Attr | | {} let attrKeys = Object.keys(attr) attrKeys.forEach(v => { node.setAttribute(v,attr[v]) }) let arr = (vnode.children || []) arr.forEach(v  => { node.appendChild(render(v)) }) return node } let dom = render(vmDom) document.body.appendChild(dom) </script>Copy the code

Results the following