【Toy-React】基于真实Dom的React简易版

///toy-react.js
class ElementWrapper {
    constructor(type) {
        this.root = document.createElement(type);
    }
    // 设置属性 id class 等  
    setAttribute(name, value) {
        this.root.setAttribute(name, value);
    }
    // 添加子元素 会一层层接后
    appendChild(component) {
        this.root.appendChild(component.root);
    }
}
//文本属性
class TextWrapper {
    constructor(content) {
        this.root = document.createTextNode(content)
    }
}

export class Component {
    constructor() {
        this.props = Object.create(null);
        this.children = [];
        this._root = null;
    }

    setAttribute(name, value) {
        this.props[name] = value;
    }
    appendChild(component) {
        this.children.push(component);
    }

    get root() {
        if (!this._root) {
            this._root = this.render().root;
        }
        return this._root;
    }
}
// jsx解析语法  递归
export function createElement(type, attributes, ...children) {
    let e;
    //单纯的element 
    if (typeof type === 'string') {
        e = new ElementWrapper(type);
    } else {
        //带标签
        e = new type;
    }
    //type为一个自定义的组件时 
    for (const p in attributes) {
        e.setAttribute(p, attributes[p])
    }
    let insertChildren = (children) => {
        for (const child of children) {
            if (typeof child === 'string') {
                child = new TextWrapper(child);
            }

            if (typeof child === 'object' && child instanceof Array) {
                insertChildren(child)
            } else {
                e.appendChild(child);
            }
        }
    }
    insertChildren(children);

    return e;
}

// 输出 render 方法
export function render(component, parentElement) {
    parentElement.appendChild(component.root)
}

main.js

import { createElement, Component, render } from './toy-react';
class MyComponent extends Component {
    render() {
        return <div>
            <h1>依赖真实节点Dom</h1>
            <h2> {this.children} </h2>
            <h2>2020/9/7/星期一/23:43</h2>
        </div>
    }
}


render(<MyComponent id="a" class="b">
    {/* style={{textAlign:"center"}} 无法解析 */}
    <div style={{ textAlign: "center" }}>bobby</div>
    <div></div>
</MyComponent>, document.body)

  dist -> main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./main.js"></script>
</body>
</html>

  

 

 意在理解 react.creatElement react如何创建一个dom节点 原理 优势 虚拟dom给web带来的性能优化

posted @ 2020-09-08 00:08  三行代码  阅读(189)  评论(0编辑  收藏  举报