美文网首页
fiber架构(简易代码)

fiber架构(简易代码)

作者: Mr无愧于心 | 来源:发表于2021-05-27 14:21 被阅读0次
    let element = {
        type:'div',
        props:{
            id: 'A1',
            children: [
                {
                    type:'div',
                    props:{ 
                        id: 'B1',
                        children: [
                            { type:'div',props:{id: 'C1', children: []} },
                            { type:'div',props:{id: 'C2', children: []} },
                        ]
                    },
                },
                {
                    type:'div',props:{id: "B2", children: []}
                }
            ]
        },
    }
    let container=document.getElementById('container')
    //第一个工作单元
    let workInProgressRoot={
        stateNode:container,
        props:{children:[element]}//fiber的属性
    };
    
    // 下一个fiber工作单元
    let nextUnitOfWork=workInProgressRoot;
    function workLoop(){
        // 如果有当前的工作单元,就执行他,并返回一个工作单元
        while(nextUnitOfWork){
            nextUnitOfWork=performUnitOfWork(nextUnitOfWork);
        }
        if(!nextUnitOfWork){
            commitRoot()
        }
    };
    function commitRoot(){
        let currentFiber=workInProgressRoot.firstEffect;
        while(currentFiber){
            if(currentFiber.effectTag==='PLACEMENT'){
                currentFiber.return.stateNode.appendChild(currentFiber.stateNode);
            }
            currentFiber=currentFiber.nextEffect;
        }
    }
    // beginWork 创建此fiber的真实dom 通过虚拟dom创建fiber树结构
    function performUnitOfWork(wordInProgressFiber){
        beginWork(wordInProgressFiber)// 创建fiber单元
        if(wordInProgressFiber.child){
            return wordInProgressFiber.child// 如果有儿子就返回儿子
        }
    
        while(wordInProgressFiber){
            //如果没有儿子当前节点就结束完成了
            completeUnitOfWork(wordInProgressFiber)
            if(wordInProgressFiber.sibling){//如果有弟弟,返回弟弟
                return wordInProgressFiber.sibling
            }
            wordInProgressFiber=wordInProgressFiber.return;// 先指向父亲,再循环取到叔叔
        }
    }
    
    function beginWork(wordInProgressFiber){
        console.log('beginWork',wordInProgressFiber.props.id)
        if(!wordInProgressFiber.stateNode){
            wordInProgressFiber.stateNode=document.createElement(wordInProgressFiber.type);
            for(let key in wordInProgressFiber.props){
                if(key !=='children'){
                    wordInProgressFiber.stateNode[key]=wordInProgressFiber.props[key];
                }
            }
        }// 在beginWork中不会挂载dom元素
        //创建子fiber
        let previousFiber=null;
        wordInProgressFiber.props.children.forEach((child,index) => {
            let childFiber={
                type:child.type,// dom节点类型
                props:child.props,
                return:wordInProgressFiber,//父fiber
                effectTag:'PLACEMENT',// 副作用:表示这个fiber对应的dom节点需要被插入到页面中去 父dom中
            }
            if(index===0){
                wordInProgressFiber.child=childFiber
            }else{
                previousFiber.sibling=childFiber
            }
            previousFiber=childFiber
        });
    }
    
    function completeUnitOfWork(wordInProgressFiber){
        console.log('completeUnitOfWork',wordInProgressFiber.props.id);
        // 构建副作用链effectList 只有哪些有副作用的节点
        let returnFiber = wordInProgressFiber.return;
        if(returnFiber){
            // 把当前fiber的有副作用子链表挂载到父亲身上
            if(!returnFiber.firstEffect){
                returnFiber.firstEffect=wordInProgressFiber.firstEffect;
            }
            if(wordInProgressFiber.lastEffect){
                if(returnFiber.lastEffect){
                    returnFiber.lastEffect.nextEffect=wordInProgressFiber.firstEffect 
                }
                returnFiber.lastEffect=wordInProgressFiber.lastEffect;
            }
            //再把自己挂到后面
            if(wordInProgressFiber.effectTag){
                if(returnFiber.lastEffect){
                    returnFiber.lastEffect.nextEffect=wordInProgressFiber 
                }else{
                    returnFiber.firstEffect=wordInProgressFiber;
                }
                returnFiber.lastEffect=wordInProgressFiber;
            }
    
        }
    }
    
    
    requestIdleCallback(workLoop)
    

    相关文章

      网友评论

          本文标题:fiber架构(简易代码)

          本文链接:https://www.haomeiwen.com/subject/lcvpjltx.html