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)
网友评论