react虚拟dom浅析

//说明
/**
 * ReactDOM.render(
 *  <h1>Hello, world!</h1>,
 *  document.getElementById('root')
 * );
 * babel转译之后
 * ReactDOM.render(React.createElement("h1", null, "Hello, world!"), 
 * document.getElementById('root'));
 * 所以首先需要一个函数createElement来转写html标签语法(JSX)
 * 然后需要一个render函数挂载到dom里
 */
let React = (function(){
    class Component{
        static isReactComponent = true;//区分是函数还是类的标识(class通过babel转译后也是函数)
        constructor(props){
            this.props = props;
        }
    }
    function ReactElement(type,props){
        const element = {type,props}
        return element;
    }
    function createElement(type,config,children){
        let propsName;
        const props = {};
        for(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 ReactElement(type,props);
    }
    return {
        createElement,Component
    }
})()
let ReactDom = (function(){
    function render(element,parentNode){
        if(typeof element == 'string' || typeof element == 'number'){
            return parentNode.appendChild(document.createTextNode(element));
        }
        let {type,props} = element;
        if(type.isReactComponent){
            let returnElement =new type(props).render();
            type = returnElement.type;
            props = returnElement.props;
        }else if(typeof type == 'function'){
            let returnElement = type(props);
            type = returnElement.type;
            props = returnElement.props;
        }
        
        let domElement = document.createElement(type);
        for(let propName in props){
            if(propName == 'className'){
                domElement.className = props[propName];
            }else if(propName == 'style'){
                let styleObj = props[propName];
                for(let attr in styleObj){
                    domElement.style[attr] = styleObj[attr];
                }
            }else if(propName == 'children'){
                let children = Array.isArray(props.children)?props.children:[props.children];
                children.forEach(child=>render(child,domElement));
            }else{
                domElement.setAttribute(propName,props[propName])
            }
        }
        parentNode.appendChild(domElement)
    }
    return {
        render
    }
})()
//普通使用
let element = React.createElement('h1',{
    className:'title',
    style:{
        color:'red',
        fontSize:'50px'
    }
},"hello",React.createElement("span",null,"常规写法"));
ReactDom.render(element,document.getElementById('root'));

//函数组件调用
function welcome1(props){
    return React.createElement("h1",{id:'welcome'},props.name,props.age)
}

let element1 = React.createElement(welcome1,{name:'函数',age:'10'})
ReactDom.render(element1,document.getElementById('root'))

//类组件调用
class Welcome2 extends React.Component{
    render(){
    return React.createElement("h1",{id:'welcome'},this.props.name,this.props.age)
    }
}

let element2 = React.createElement(Welcome2,{name:'类',age:'10'})
ReactDom.render(element2,document.getElementById('root'))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值