zoukankan      html  css  js  c++  java
  • [React]虚拟DOM

    1.虚拟DOM(virtual DOM)

    我们在render()方法中书写的JSX代码,既有js代码又有html代码,但是实际上浏览器不能识别JSX。

    let element = (<div className="red">
      <span>hehe</span>
    </div>)

    需要通过babel-loader将其转化为js代码。实际上就是转为React中的createElement()方法调用。

    var element = React.createElement("div", {
      className: "red"
    }, React.createElement("span", null, "hehe"));

    该方法返回一个对象,这个对象的内容和DOM类似,但是不是真实的DOM,所以称之为虚拟DOM。

    {
        "type": "div",
        "props": {
            "className": "red",
            "children": {
                "type": "span",
                "props": {
                    "children": "hehe"
                }
            }
        }
    }

    最后浏览器展示的DOM是通过ReactDOM.render()方法处理后,成为真实DOM。

    2.createElement()方法模拟实现

    function createElement(type, config, children) {
        console.log(children)
        const props = {};
        for (let propName in config) {
            props[propName] = config[propName];
        }
        const childrenLength = arguments.length - 2;
        if (childrenLength === 1) {
            props.children = children; // 为元素,文本,数字
        } else if (childrenLength > 1) { // 为数组
            props.children = Array.from(arguments).slice(2);
        }
        return { type, props}
    }

    3.render方法模拟实现

    function render(element, container) {
        if (typeof element === 'string' || typeof element === 'number') { // 文本或者数字
           container.appendChild(document.createTextNode(element));
           return;
        }
        let type = element.type;
        let props = element.props;
    
        if (typeof type === 'function') { // 函数组件或者类组件
            if (type.isComponent) { //
                element = (new type(props)).render();
            } else {
                element = type(props);
            }
            type = element.type;
            props = element.props;
        }
        let domEle = document.createElement(type);
        for (let propName in props) {
            if (propName === 'className') {
                domEle.className = props[propName];
            } else if(propName === 'style') {
                const styleObj = props[propName];
                for(let styleProp in styleObj) {
                    domEle.style[styleProp] = styleObj[styleProp];
                }
            } else if(/^on[A-Z]/.test(propName)) {
                domEle[propName.toLowerCase()] = props[propName];
            } else if(propName === 'children') {
                const children = Array.isArray(props[propName]) ? props[propName] : [props.children];
                children.forEach(child => render(child, domEle));
            }
        }
        container.appendChild(domEle);
    }
  • 相关阅读:
    poj 1904 King's Quest
    【BZOJ】1051: [HAOI2006]受欢迎的牛
    hdu 2767 Proving Equivalences
    hdu 3234 Exclusive-OR
    poj 1988 Cube Stacking
    poj 1733 Parity game
    hdu 3047 Zjnu Stadium 带权并查集
    poj 1182 食物链 种类并查集
    HDU 3749 Financial Crisis
    【BZOJ】1046 : [HAOI2007]上升序列
  • 原文地址:https://www.cnblogs.com/lyraLee/p/11489650.html
Copyright © 2011-2022 走看看