react的虚拟DOM转换成DOM过程

1:babel的支持

    我们知道HTML5文本中,我们是无法使用jsx的,例如,下面的定义就会出错:

   let vdom = (


hello ,World!

你好吗

)

    babel也提供了远程cdn支持,所以我们只需要在头部引用

     就行了。

2:vdom转换过程

    当引入这个js文件后,你会出现下面的一行出错。

,babel默认解析jsx会去引入React,我们这没有React,当然就会出错。我们使用指令 ,/** @jsx hyperScript **/,定义一个自己的jsx渲染器,其中hyperScript 表示方法名字。

于是,我们的代码成了下面这个样子

/** @jsx hyperScript **/
let vdom = (


hello ,World!

你好吗
   

 )

function hyperScript(nodeName , attributes , ...args){

}//这个方法用来解析jsx

我们书写这个方法。在jsx中,我们认为每一个虚拟DOM其实就是一个json文件。例如

,就会等价于

{ nodeName :"div" , attrbutes : { id : "box"} , children : []  }。下面我们的hyperScript就会长这样

function hyperScript(nodeName , attributes , ...args){

//返回虚拟DOM, 虚拟DOM结构,用[].concat(...args) 连接所有子节点,返回构建完成的JSON。

let children =  args.length ? [].concat(...args) : [];
return {nodeName,attributes,children  }

}

书写玩这个方法后,打印出vdom的结构

console.log( vdom )

console.log( JSON.stringify( vdom , null , 2) )

react的虚拟DOM转换成DOM过程_第1张图片

是不是发现vdom解析后就是一个json数据。

剩下的就是编写一个render方法了。render接受一个vdom,返回一个真实的DOM。

function render( vnode ){
//如果是字符,直接创建文本返回
if(vnode.split){
return document.createTextNode( vnode )
}
//node是一个真实DOM
let node = document.createElement( vnode.nodeName );
//获取属性
let attrs = vnode.attrbutes || {} ;
//给这个node节点遍历加上属性
Object.keys( attrs ).forEach( item => node.setAttribute( item , attrs[item] ) );
//如果有子元素,递归处理子元素并且给属性赋值,没有就结束
( vnode.children || [] ).forEach( item => node.appendChild( render(item) ) );
//返回node 
return node;
}

这时,我们定义一个let dom =  render( vdom ); console.log( dom )

打印出dom,得到解析完成的真实DOM节点了。是不是发现Vdom也不是那么神奇。

最后,贴上完整html代码, 懒人直接运行就行了。





Document







你可能感兴趣的:(react的虚拟DOM转换成DOM过程)